Почему удар игнорирует новые строки при выполнении для цикла по содержанию строки C-стиля?

Пустой указатель нечувствителен к регистру.

От документация :

существует только одно значение пустого указателя типа, и это нечувствительно к регистру ПУСТОЙ УКАЗАТЕЛЬ ключевого слова.

5
задан EMPraptor 30 October 2009 в 18:02
поделиться

4 ответа

Измените свой $ IFS , чтобы изменить способ разделения текста на слова в bash.

Примечание редактора:
Этот ответ был принят, поскольку он предоставляет ссылку на информацию, которая в конечном итоге объясняет основные проблемы.
Однако обратите внимание, что проблема OP не может не быть решена простым изменением $ IFS , потому что $ IFS не применяется к строкам в кавычках .

6
ответ дан 18 December 2019 в 14:48
поделиться

Bash не выполняет расширение слов в кавычках в этом контексте. Например:

$ for i in "a b c d"; do echo $i; done
a b c d

$ for i in a b c d; do echo $i; done
a
b
c
d

$ var="a b c d"; for i in "$var"; do echo $i; done
a b c d

$ var="a b c d"; for i in $var; do echo $i; done
a
b
c
d

В комментарии вы заявили: «IFS = '\ n' также работает. Не работает IFS = $ '\ n'. Я сейчас очень запутался».

In IFS = '\ n' , вы устанавливаете разделители (множественное число) для двух символов обратной косой черты и «n». Итак, если вы сделаете это (вставив «X» в середину «\ n»), вы увидите, что произойдет. Он обрабатывает последовательности "\ n" буквально, несмотря на то, что они у вас есть в $ '' :

$ IFS='\n'; for i in $'a\Xnb\nc\n'; do echo $i; done; rrifs
a X b
c

Edit 2 (в ответ на комментарий):

Он видит '\ n' как два символа (не новая строка) и $ ' a \ Xnb \ nc \ n ' как буквальная строка из 10 символов (без символов новой строки), затем echo выводит строку и интерпретирует последовательность "\ n" как новую строку (поскольку строка " помечено "для интерпретации"), но поскольку оно заключено в кавычки, оно рассматривается как одна строка, а не слова, разделенные $ IFS .

Попробуйте это для дальнейшего сравнения:

$ c=0; for i in "a\nb\nc\n"; do echo -e "iteration $c :$i:"; c=$[c+1]; done
iteration 0 :a
b
c
:

$ c=0; for i in "a\nb\nc\n"; do echo "iteration $c :$i:"; c=$[c+1]; done
iteration 0 :a\nb\nc\n:

$ c=0; for i in a\\nb\\nc\\n; do echo -e "iteration $c :$i:"; c=$[c+1]; done
iteration 0 :a
b
c
:

$ c=0; for i in a\\nb\\nc\\n; do echo "iteration $c :$i:"; c=$[c+1]; done
iteration 0 :a\nb\nc\n:

Установка IFS не влияет на вышеуказанное.

Это работает (обратите внимание, что $ var не заключен в кавычки в операторе for ) :

$ var=$'a\nb\nc\n'
$ saveIFS="$IFS"   # it's important to save and restore $IFS
$ IFS=$'\n'        # set $IFS to a newline using $'\n' (not '\n')
$ c=0; for i in $var; do echo -e "iteration $c :$i:"; c=$[c+1]; done
iteration 0 :a:
iteration 1 :b:
iteration 2 :c:
$ IFS="$saveIFS"
7
ответ дан 18 December 2019 в 14:48
поделиться

Две причины:

  1. Ваш цикл for зацикливается только один раз: есть только один элемент для цикла, это $ '1 \ n2 \ n3 \ n4 ' строка. Если вы хотите выполнить цикл четыре раза, вы должны изменить $ IFS , как предлагает команда unwind.

  2. echo принимает эту строку и интерпретирует ее как четыре аргумента, разделенных символами новой строки. Затем он отображает все аргументы, разделенные пробелами. Если вы хотите, чтобы echo не интерпретировал входную строку, заключите ее в двойные кавычки, как в echo "$ i" .

Редактировать после редактирования вопроса:

  • Я попытался изменить $ IFS : это сработало, но я использовал export $ IFS = '\ n'

  • Во втором случае $ v интерпретируется bash в для команды , которая интерпретирует его как четыре аргумента, разделенных символами новой строки. Если вы снова хотите получить свою первую проблему, просто используйте для f в "$ v" вместо для f в $ v .

0
ответ дан 18 December 2019 в 14:48
поделиться

попробуйте

c = 0; для i в $ '1 \\ n2 \\ n3 \\ n4'; выполнить echo -e итерацию $ c: $ i :; c = $ [c + 1]; done

дополнительные обратные косые черты сохраняют escape-символы для символов новой строки, echo -e указывает echo расширять escape-символы.

0
ответ дан 18 December 2019 в 14:48
поделиться
Другие вопросы по тегам:

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