Esto es lo que tengo hasta ahora:
#!/bin/bash
while read line; do
DB=$(echo $line | cut -f1)
USER=$(echo $line | cut -f2)
PASS=$(echo $line | cut -f3)
echo DB=$DB USER=$USER PASS=$PASS
done < users.txt
Y una muestra del archivo de entrada:
drupal_1 drupal1 tmmjXSWL
drupal_2 drupal2 FHiJSYHM
drupal_3 drupal3 b7bFNj06
drupal_4 drupal4 0AaV62EL
Y salida del script:
DB=drupal_1 drupal1 tmmjXSWL USER=drupal_1 drupal1 tmmjXSWL PASS=drupal_1 drupal1 tmmjXSWL
DB=drupal_2 drupal2 FHiJSYHM USER=drupal_2 drupal2 FHiJSYHM PASS=drupal_2 drupal2 FHiJSYHM
DB=drupal_3 drupal3 b7bFNj06 USER=drupal_3 drupal3 b7bFNj06 PASS=drupal_3 drupal3 b7bFNj06
Por alguna razón, cada variable se establece en toda la línea. Cuando lo uso echo users.txt | cut -f1
en la línea de comando, devuelve el token muy bien.
$(echo $line | cut -d" " -f1)
También funciona.El problema está en el comando
echo $line
. Como no hay comillas$line
, el shell realiza la división de palabras en él, luego interpreta cada palabra como un patrón global. Pruébalo conEn su caso, las pestañas separan palabras, que luego se convierten en argumentos separados para
echo
. Elecho
comando imprime sus argumentos separados por un espacio. Por lo tanto,cut
termina recibiendo campos delimitados por espacios en lugar de campos delimitados por tabulaciones.Siempre ponga comillas dobles alrededor de las sustituciones variables
$foo
y las sustituciones de comandos$(foo)
(a menos que comprenda por qué necesita omitirlas y por qué está bien hacerlo).echo "$line"
funcionaría aquí, pero es una forma complicada de hacer lo que propones.Manteniendo su enfoque de análisis en el shell, puede hacer que el
read
comando analice la entrada en los campos.read
divide campos separados por caracteres en el valor de laIFS
variable, que consiste en un espacio y una pestaña (más una nueva línea, que no puede aparecer dentro de una línea) de forma predeterminada. Para dividir solo en pestañas, configureIFS
primero una sola pestaña. Tenga en cuenta que las pestañas iniciales y finales se ignoran y las pestañas consecutivas cuentan como una sola.read
se trata\
como un carácter especial: se ignora una barra invertida seguida de una nueva línea;\\
se convierte en una barra invertida simple. Si desea evitar este comportamiento, pase la-r
opción.fuente
IFS=$'\t'