Как прочитать полную строку в цикле «for» с пробелами

Я пытаюсь запустить цикл for для файла и хочу отобразить всю строку. Но вместо этого отображается только последнее слово. Я хочу полную линию.

for j in `cat ./file_wget_med`

do
echo $j

done

результат после запуска:

Found.

Вот мои данные:

$ cat file_wget_med
2013-09-11 14:27:03 ERROR 404: Not Found.
132
задан 11 September 2013 в 23:59

7 ответов

for цикл разделяется, когда он видит любые пробелы, такие как пробел, табуляция или перевод строки. Итак, вы должны использовать IFS (Внутренний разделитель полей) :

IFS=\n'       # make newlines the only separator
for j in $(cat ./file_wget_med)    
do
    echo "$j"
done
0
ответ дан 11 September 2013 в 23:59

for циклы разбиваются на любые пробелы (пробел, табуляция, новая строка) по умолчанию; Самый простой способ работать с одной строкой за раз - это использовать цикл while read, который разделяется на новые строки:

while read i; do echo "$i"; done < ./file_wget_med

Я бы ожидал ваша команда выплевывать по одному слову в строке (это то, что произошло, когда я проверил это с моим собственным файлом). Если что-то еще происходит, я не уверен, что может быть причиной.

0
ответ дан 11 September 2013 в 23:59
#!/bin/bash
files=`find <subdir> -name '*'`
while read -r fname; do
    echo $fname
done <<< "$files"

Проверенная работа, не тот лайнер, который вы, вероятно, хотите, но это невозможно сделать элегантно.

0
ответ дан 11 September 2013 в 23:59

Вот небольшое расширение ответа Митчелла Карри, которое мне нравится из-за небольшого количества побочных эффектов, которое позволяет избежать необходимости устанавливать переменную:

0
ответ дан 11 September 2013 в 23:59

Я бы написал так:

cat ./file_wget_med | while read -r j
do
    echo $j
done

, так как он требует наименьших изменений в исходном скрипте (за исключением решения с использованием IFS, но оно изменяет поведение bash не только для этого цикла). контрольное заявление).

0
ответ дан 11 September 2013 в 23:59

Дэндальф очень близко подошел к функциональному решению, но НИКОГДА НЕ ДОЛЖНО пытаться присвоить результат неизвестных величин ввода (т. Е. find ~/.gdfuse -name '*') переменным! Или, по крайней мере, попытаться сделать это через переменную массива; если вы настаиваете на том, чтобы быть таким ленивым! Итак, вот решение Дэндальфа, выполненное без опасного маневра; и всего в одной строке

while read -r fname; do
  echo $fname;
done <<< `find ~/.gdfuse -name '*'
0
ответ дан 11 September 2013 в 23:59

Mapfile является удобным способом считать строки из файла в индексный массив, не столь портативный, как читает , но немного быстрее. При помощи для цикла Вы стараетесь не создавать подоболочку.

#!/bin/bash

mapfile -t < file.txt

for line in "${MAPFILE[@]}"; do
    echo $line
done

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

Пример:

#!/bin/bash

a=0
printf %s\\n {0..5} | while read; do
  ((a++))
done
echo $a # 'a' will always be 0.

(Лучшее решение):

#!/bin/bash

b=0
while read; do
  ((b++))
done < <(printf %s\\n {0..5})

echo $b # 'b' equal to 6 (works as expected).
0
ответ дан 10 October 2019 в 10:55

Другие вопросы по тегам:

Похожие вопросы: