Как открыть новую строку, используя цикл for?


9

В разных местах в Интернете я нашел:

\015 
\012
\x0a - hex
\n
\r

все как синонимы для различных новых строк / возвратов каретки ...

Но в этом небольшом сценарии я не могу распознать, когда сталкиваюсь с новой строкой - может кто-нибудь сказать мне, что я должен проверять в строке if?

#!/bin/bash

test="this is a
test"

for a in "$test"; do

        if [[ "$a" == '\012' ]] ; then
                echo "FOUND NEWLINE"
        fi

echo "$a"

done

1
У меня тупой вопрос. Зачем тебе это нужно? Если вы читаете входные данные построчно cat | while read line; do ...; done, вы знаете, что для каждой итерации был возврат каретки. Если ваши входные данные могут быть файлами \rбез \n, просто преобразуйте файл tr '\r' '\n'во время обработки ввода. Если вам просто нужно знать , если есть несколько строк: wc -l.
— nicerobot

Добро пожаловать в Stack Exchange. Пожалуйста, не редактируйте свой вопрос таким образом, так как это делает существующие ответы бессмысленными. Поскольку вы нашли способ решить свою проблему, вы можете опубликовать его как альтернативный ответ.
— Жиль "ТАК - перестань быть злым"

@nicerobot, если нет новой строки вообще, то wc -lвернет 0; Вы должны добавить это как ответ
— Arcege

@ lolfrog решение не должно быть в вопросе, вы должны отметить ответ, который имеет решение
— Arcege

Ответы:


6

Если вы непосредственно используете строки в forцикле, он будет работать для каждого слова (здесь одно слово: весь контент, $testпоскольку он указан в кавычках), а не для каждого символа. Вам нужно использовать whileцикл с read, чтобы анализировать букву за буквой, или вводить числовой параметр, который будет перебирать строку.

Кроме того, при использовании readнеобходимо убедиться, что символы новой строки и пробелы не интерпретируются как разделители, и заставить readчитать один символ за раз.

Вот рабочая версия:

#!/bin/bash

test="this is a
test"

printf %s "$test" | while IFS= read -r -N 1 a; do

        if [[ "$a" == $'\n' ]] ; then
                echo "FOUND NEWLINE"
        fi

printf %s "$a"

done

Вы можете заменить $'\n'на $'\012'или $'\x0a', так как все они представляют один и тот же код новой строки. Но это не то же самое, что \015или \r- это означает возврат каретки (возврат к началу строки). В системах Linux переводы строки представлены с использованием \n, но в Windows, например, они представлены последовательностью \r\nвместо. Вот почему, если у вас есть текстовый файл из Windows, вы можете обнаружить новые строки, также выполнив поиск \r.


Короче говоря, он превращает экранированную заключенную в кавычки последовательность, как \nв ее байтовое представление, так что вам не нужно помещать уродливые, заключенные в кавычки разрывы строк в вашем операторе test.
— rozcietrzewiacz

4

Вы можете легко проверить наличие новых строк в переменной с помощью bash:

[[ $var = *$'\n'* ]]

Я считаю более удобным использовать:

declare -r EOL=$'\n' TAB=$'\t' # at top of script
..
if [[ $var = *$EOL* ]]; then # to test (no field-splitting in [[ )

1

Я бы предложил использовать, trа затем test:

if [ -n "$(tr -cd '\n\r' < datafile)" ]; then
    echo "NEWLINE FOUND"
fi

tr -cdУдаляет все , кроме перевода строки / возврат каретки. Если в файле есть новые строки, то будет вывод, из которого -nтест вернет true.


Это не будет работать для файлов, не содержащих \rs, потому что подстановка команд удаляет завершающие символы новой строки ( "$(printf '\n\n\n\n\n')"это пустая строка).
— Стефан Шазелас
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.