Aqui está o que eu tenho até agora:
#!/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
E uma amostra do arquivo de entrada:
drupal_1 drupal1 tmmjXSWL
drupal_2 drupal2 FHiJSYHM
drupal_3 drupal3 b7bFNj06
drupal_4 drupal4 0AaV62EL
E saída do 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 algum motivo, cada variável é definida para a linha inteira. Quando eu uso echo users.txt | cut -f1
na linha de comando, ele retorna o token muito bem.
$(echo $line | cut -d" " -f1)
também funciona.O problema está no comando
echo $line
. Como não há aspas$line
, o shell executa a divisão de palavras nele e interpreta cada palavra como um padrão brilhante. Experimente comNo seu caso, as guias separam palavras, que então se tornam argumentos separados para
echo
. Oecho
comando imprime seus argumentos separados por um espaço. Portanto,cut
acaba recebendo campos delimitados por espaço em vez de campos delimitados por tabulação.Sempre coloque aspas duplas em torno de substituições de variáveis
$foo
e substituições de comandos$(foo)
(a menos que você entenda por que precisa deixá-las de fora e por que é bom fazê-lo).echo "$line"
funcionaria aqui, mas é uma maneira complicada de fazer o que você propõe.Mantendo sua abordagem de análise no shell, você pode fazer o
read
comando analisar a entrada em campos.read
divide os campos separados por caracteres no valor daIFS
variável, que consiste em um espaço e uma guia (mais uma nova linha, que não pode ocorrer dentro de uma linha) por padrão. Para dividir apenas em guias, definaIFS
primeiro uma única guia. Observe que as guias iniciais e finais são ignoradas e as guias consecutivas contam como uma única.read
trata\
como um caractere especial: uma barra invertida seguida por uma nova linha é ignorada;\\
torna-se uma única barra invertida. Se você deseja evitar esse comportamento, passe a-r
opçãofonte
IFS=$'\t'