2015-03-11 3 views
0

Я написал следующую команду для цикла над множеством строк во втором столбце моего файла, а затем выполните сортировку для каждой строки в столбце 11, затем возьмите второй и одиннадцатый столбцы и подсчитайте количество уникальные вхождения. Очень просто, но кажется, что он входит в бесконечный цикл, и я не понимаю, почему. Я был бы очень признателен за вашу помощь.Inifinite loop in bash

for item in $(cat file.txt | cut -f2 -d " "| uniq) 
do 
    sort -k11,11 file.txt | cut -f2,11 -d " " | uniq -c | sort -k2,2 > output 
done 
+2

Вы понимаете, что это будет перезаписывать 'output' с самого начала на каждом проходе, уничтожая предшествующие итерации? Какой смысл здесь? –

+2

Непонятно, что вы хотите сделать. Не могли бы вы предоставить некоторый ввод проб и желаемый результат? Мне кажется, что вы используете много труб для чего-то, что должно быть более прямым. – fedorqui

+4

Не выглядит для меня бесконечным циклом. Элемент 'для элемента в $ (...)' вычисляется только один раз, поэтому это не будет проблемой. Попробуйте включить xtrace с помощью 'set -o xtrace', затем запустите команду. Он покажет вам каждую команду при ее запуске. –

ответ

1

Там нет бесконечного цикла здесь, но это очень глупый цикл (который занимает много времени, чтобы работать, в то время как не достижение указанной цели скрипта). Давайте посмотрим, как можно было бы достичь этой цели более здраво:


Использование временного файла для counts.txt, чтобы избежать необходимости повторно шаги sort, cut и uniq на каждой итерации:

sort -k11,11 file.txt | cut -f2,11 -d " " | uniq -c >counts.txt 
while read -r item; do 
    fgrep -e " ${item}" counts.txt 
done < <(cut -f2 -d' ' <file.txt | uniq) 

еще лучше , с использованием ассоциативных массивов bash 4 и без временного файла:

# reads counts into an array 
declare -A counts=() 
while read -r count item; do 
    counts[$item]=count 
done < <(sort -k11,11 file.txt | cut -f2,11 -d " " | sort | uniq -c) 

# reads counts back out 
while read -r item; do 
    echo "$item ${counts[$item]}" 
done < <(cat file.txt | cut -f2 -d " "| sort | uniq) 

... это говорит, что это только если вы хотите использовать sort для заказа на извлечение данных. Если вам не нужно это делать, последняя часть может быть заменена как таковая:

# read counts back out 
for item in "${!counts[@]}"; do 
    echo "$item ${counts[$item]}" 
done