Bagaimana menemukan baris baru menggunakan for for?

8

Di berbagai tempat di web saya temukan:

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

semua sebagai sinonim untuk berbagai baris baru / pengembalian carriage ...

Tetapi dalam skrip kecil ini saya tidak bisa mengenali ketika saya menemukan baris baru - dapatkah seseorang memberi tahu saya apa yang harus saya periksa di baris if?

#!/bin/bash

test="this is a
test"

for a in "$test"; do

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

echo "$a"

done
lolfrog
sumber
1
Saya punya pertanyaan bodoh. Mengapa Anda perlu melakukan ini? Jika Anda membaca input baris demi baris cat | while read line; do ...; done, Anda tahu ada carriage return untuk setiap iterasi. Jika input Anda dapat berupa file \rtanpa \n, cukup ubah file tr '\r' '\n'saat memproses input. Jika Anda hanya perlu tahu jika ada beberapa baris: wc -l.
nicerobot
Selamat datang di Stack Exchange. Tolong jangan edit pertanyaan Anda dengan cara ini, karena membuat jawaban yang ada menjadi tidak berarti. Karena Anda telah menemukan cara untuk menyelesaikan masalah Anda, Anda dapat mempostingnya sebagai jawaban alternatif.
Gilles 'SO- stop being evil'
@nicerobot jika tidak ada baris baru sama sekali, maka wc -lakan kembali 0; Anda harus menambahkan itu sebagai jawaban
Arcege
@ lolfrog solusinya tidak boleh dalam pertanyaan, Anda harus menandai jawaban yang memiliki solusinya
Arcege

Jawaban:

6

Jika Anda secara langsung menggunakan string di bawah satu forlingkaran, itu akan berfungsi per-kata (di sini pada satu kata: seluruh konten $testsejak dikutip), bukan per-karakter. Anda perlu menggunakan whileloop dengan readuntuk mengurai huruf-demi-huruf, atau untuk memperkenalkan parameter numerik yang akan diulang di atas string.

Selain itu, saat menggunakan read, Anda perlu memastikan bahwa baris baru dan ruang putih tidak diartikan sebagai pembatas dan memaksa readuntuk membaca satu karakter sekaligus.

Ini versi yang berfungsi:

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

Anda dapat mengganti $'\n'dengan $'\012'atau $'\x0a', karena semuanya mewakili kode baris baru yang sama. Tetapi tidak sama dengan \015atau \r- ini singkatan dari carriage return (kembali ke awal baris). Pada sistem Linux, baris baru diwakili menggunakan \n, tetapi pada Windows misalnya, mereka diwakili oleh urutan \r\nsebagai gantinya. Itu sebabnya jika Anda memiliki file teks dari Windows, Anda dapat mendeteksi baris baru juga dengan mencari \r.

rozcietrzewiacz
sumber
Singkatnya, ini mengubah urutan escape yang dikutip seperti \nmenjadi representasi byte, sehingga Anda tidak perlu menempatkan jeda baris yang tampak jelek dan dikutip dalam pernyataan pengujian Anda.
rozcietrzewiacz
4

Anda dapat memeriksa baris baru dalam variabel dengan sangat mudah di bash dengan:

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

Saya merasa lebih nyaman untuk digunakan:

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

Saya sarankan menggunakan trdan kemudian test:

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

The tr -cdmenghapus segala sesuatu kecuali baris / enter. Jika ada baris baru dalam file, maka akan ada output dari mana -ntes akan mengembalikan true.

Arcege
sumber
Itu tidak akan berfungsi untuk file yang tidak mengandung \rs karena penggantian perintah menghapus karakter baris baru yang tertinggal ( "$(printf '\n\n\n\n\n')"adalah string kosong).
Stéphane Chazelas