Oto co mam do tej pory:
#!/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
I próbka pliku wejściowego:
drupal_1 drupal1 tmmjXSWL
drupal_2 drupal2 FHiJSYHM
drupal_3 drupal3 b7bFNj06
drupal_4 drupal4 0AaV62EL
I dane wyjściowe ze skryptu:
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
Z jakiegoś powodu każda zmienna jest ustawiona na całą linię. Kiedy używam echo users.txt | cut -f1
z wiersza poleceń, token jest w porządku.
$(echo $line | cut -d" " -f1)
działa również.Problem leży w poleceniu
echo $line
. Ponieważ nie ma żadnych cudzysłowów$line
, powłoka wykonuje na nim podział słów, a następnie interpretuje każde słowo jako wzór globowania. Wypróbuj to zW twoim przypadku zakładki oddzielają słowa, które następnie stają się osobnymi argumentami
echo
.echo
Polecenie wypisuje argumenty oddzielone spacją. Wcut
rezultacie otrzymujemy pola rozdzielane spacjami zamiast pól rozdzielanych tabulatorami.Zawsze umieszczaj podwójne cudzysłowy wokół podstawień zmiennych
$foo
i podstawień poleceń$(foo)
(chyba że rozumiesz, dlaczego musisz je pominąć i dlaczego jest to w porządku).echo "$line"
działałoby tutaj, ale jest to skomplikowany sposób robienia tego, co proponujesz.Zachowując podejście do analizowania w powłoce, możesz sprawić, aby
read
polecenie przeanalizowało dane wejściowe w polach.read
domyślnie dzieli pola rozdzielone znakami w wartościIFS
zmiennej, która składa się ze spacji i tabulatora (oraz nowego wiersza, który nie może wystąpić wewnątrz linii). Aby podzielić tylko na kartach,IFS
najpierw ustaw jedną kartę. Pamiętaj, że początkowe i końcowe karty są ignorowane, a kolejne karty liczą się jako jedna karta.read
traktuje\
jako znak specjalny: odwrotny ukośnik, po którym następuje nowa linia, są ignorowane;\\
staje się pojedynczym ukośnikiem odwrotnym. Jeśli chcesz uniknąć tego zachowania, podaj tę-r
opcję.źródło
IFS=$'\t'