2011-07-29 13 views
9

Próbuję wykonać polecenie dla każdej linii pochodzącej z polecenia cat. Opieram to na przykładowym kodzie, który dostałem od dostawcy.Wydrukuj dane wyjściowe instrukcji cat w pętli skryptu Bash

Oto scenariusz:

for tbl in 'cat /tmp/tables' 
do 
    echo $tbl 
done 

więc spodziewałem wyjście być każda linia w pliku. Zamiast tego otrzymuję to:

cat 
/tmp/tables 

To oczywiście nie jest to, co chciałem.

Zamierzam zastąpić echo rzeczywistą komendą, która łączy się z bazą danych.

Każda pomoc w wyprostowaniu tego zostanie bardzo doceniona.

Odpowiedz

14

Używasz niewłaściwego rodzaju ofert.

Musisz użyć cudzysłowów, a nie pojedynczego cudzysłowu, aby argument był programem działającym i wyodrębnić zawartość do forloop.

for tbl in `cat /tmp/tables` 
do 
    echo "$tbl" 
done 

także dla lepszej czytelności (jeśli używasz bash), można napisać go jako

for tbl in $(cat /tmp/tables) 
do 
    echo "$tbl" 
done 

Jeśli twoje oczekiwania są, aby każdy wiersz (for-pętle powyżej daje każde słowo), to może być lepiej wyłączyć za pomocą xargs, jak to

cat /tmp/tables | xargs -L1 echo 

lub jako pętla

cat /tmp/tables | while read line; do echo "$line"; done 
+1

Wiedziałem, że to było coś tak głupiego. Dzięki. – geoffrobinson

2

cudzysłowu powinny być backticks:

for tbl in `cat /etc/tables` 

Chociaż, to nie będzie Ci wejść/wyjść po linii, ale po słowie. Aby przetworzyć linia po linii, należy spróbować coś takiego:

cat /etc/tables | while read line 
    echo $line 
done 
3

Z pętli while:

while read line 
do 
echo "$line" 
done < "file" 
2
while IFS= read -r tbl; do echo "$tbl" ; done < /etc/tables 

czytać this.

0

Można zrobić wiele parsowania w bashu przez redefiniowania IFS (wejście Pole separatora), na przykład

IFS='\t\n' 
for tbl in `cat /tmp/tables` 
do 
    echo "$tbl" 
done 
+0

'\ t \ n'? Czy próbowałeś tego w bash? Zostanie podzielony na "\", "t", "n", niepomocny. – kubanczyk