2012-02-25 3 views
0

Я получаю какое-то странное поведение из цикла for, который читает каждую строку в файле и после каждой строки читает каждое слово. Чтение пропускает последнее слово в каждой строке. Я думаю, что мне, возможно, придется указать, что оба пробела и новая строка являются разделителями, но я не узнал, как это сделать. Вот часть сценария, который имеет значение:«Чтение» пропущенное последнее слово в каждой строке

cat $i | while read line  
    do 
     echo $line 
     sleep 1 
     #Process each word 
     echo $line | while read -d ' ' word 
     do 
      echo $word 
      sleep 1 
     done 
    done 
+0

Избегайте ненужных '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' делать …; done <$ i' – knittl

ответ

2

Вы видели How to split one string into multiple strings separated by at least one space in bash shell?? может быть, вы могли бы просто сделать:

for word in $line 
do 
    echo $word 
    sleep 1 
done 
+0

Кажется, что это работает как шарм, думаю, я был слишком повешен, используя чтение, так как я использую его для чтения файла. – Asgeir

+0

Не уверен, но я думаю, что это будет подвергать $ line обычным расширениям оболочки, которые могут оказаться больше, чем вы хотите. Вы захотите поэкспериментировать с тем, что происходит с входными строками, содержащими двойные и одиночные кавычки и обратные линии (сбалансированные и несбалансированные) и знаками доллара ('$'). Если это окажется для вас проблемой, вы можете рассмотреть решение, основанное на 'fmt', которое я предлагаю ниже. –

2

Синтаксис команды for является:

 for name [ [in [words ...] ] ; ] do commands; done 

Развернуть слова и выполнить команды один раз для каждого члена в полученном списке с именем, связанным с текущим элементом ,

cat $i | while read line  
do 
    echo $line 
    sleep 1 
    #Process each word 
    for word in $line 
    do 
     echo $word 
     sleep 1 
    done 
done 
+0

Кажется, что это работает как шарм, предполагаю, что я слишком повесил трубку на чтение, так как я использую его для чтения файла – Asgeir

0

Попробуйте использовать команду вырезать вместо чтения -d

0

Если вам не нужно помнить границы строки, команда fmt может быть полезным. fmt пересчитывает обычный текст на stdin в заданную максимальную длину строки, и поэтому, если вы даете ему максимальную длину строки, он заканчивает разбиение каждого слова ввода на свою собственную строку. Для ваших проблем, возможно,

cat $1 | 
fmt -1 | 
while read word 
do 
    # do something with $word 
end 

Обратите внимание, что вы потеряли все границы оригинальных линий здесь, и вы зависимы от определения fmt «s о том, что такое слово. Если по какой-то причине вам действительно нужны границы линий, вы можете подумать о чем-то вроде

cat $1 | 
while read line 
do 
    # do something with $line 
    echo "$line" | 
    fmt -1 | 
    while read word 
    do 
     # do something with $word 
    done 
done 
Смежные вопросы