Como descobrir uma nova linha usando um loop for?

8

Em vários lugares da web que encontrei:

5 
2
\x0a - hex
\n
\r

todos como sinônimos de várias novas linhas / retornos de carro ...

Mas neste pequeno script eu não posso reconhecer quando me deparo com uma nova linha - alguém pode me dizer o que eu deveria estar verificando na linha if?

#!/bin/bash

test="this is a
test"

for a in "$test"; do

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

echo "$a"

done
    
por lolfrog 22.12.2011 / 14:50

3 respostas

6

Se você usar diretamente strings sob um loop for , ele funcionará por palavra (aqui em uma palavra: todo o conteúdo de $test desde sua citação), não por caractere . Você precisa usar um while loop com read para analisar letra por letra ou para introduzir um parâmetro numérico que interaja sobre a string.

Além disso, ao usar read , você precisa garantir que novas linhas e espaços em branco não sejam interpretados como delimitadores e forçar read a ler um caractere por vez.

Aqui está uma versão de trabalho:

#!/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

Você pode substituir $'\n' por $'2' ou $'\x0a' , pois todos eles representam o mesmo código de nova linha. Mas não é o mesmo que 5 ou \r - isso significa retorno de carro (retorno ao início da linha). Nos sistemas Linux, as novas linhas são representadas usando \n , mas no Windows, por exemplo, elas são representadas por uma sequência de \r\n . É por isso que, se você tivesse um arquivo de texto do Windows, também poderia detectar novas linhas pesquisando \r .

    
por 22.12.2011 / 14:55
4

Você pode verificar novas linhas em uma variável com muita facilidade no bash com:

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

Acho mais conveniente usar:

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

Sugiro usar tr e, em seguida, test :

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

O tr -cd remove tudo, exceto as novas linhas / retornos de carro. Se houver novas linhas no arquivo, haverá uma saída a partir da qual o teste -n retornará verdadeiro.

    
por 22.12.2011 / 15:05