forループを使用して新しい行を見つける方法は?


8

私が見つけたウェブ上のさまざまな場所で:

\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
ばかげた質問があります。なぜこれを行う必要があるのですか?入力を1行cat | while read line; do ...; doneずつ読み取ると、反復ごとに改行があったことがわかります。入力が\rなしのファイルである場合は、入力の処理中\nにファイルtr '\r' '\n'を変換するだけです。:あなただけの複数の行があるかどうかを知る必要がある場合wc -l
nicerobot

Stack Exchangeへようこそ。既存の回答が無意味になるため、この方法で質問を編集しないでください。問題を解決する方法を見つけたので、それを代替回答として投稿できます。
Gilles「SO-邪悪なことをやめなさい」

@nicerobotは、改行がまったくない場合はwc -l0を返します。あなたはそれを答えとして追加する必要があります
Arcege

@lolfrog解決策は質問に含めないでください。解決策のある答えをマークする必要があります
Arcege

回答:


6

forループで文字列を直接使用する場合、文字単位ではなく、単語単位(ここでは1つの単語:$test引用符で囲まれた内容全体)で機能します。文字ごとに解析するため、または文字列を反復する数値パラメーターを導入するために、whileループを使用する必要がありreadます。

また、を使用readする場合は、改行と空白が区切り文字として解釈されないようにreadし、一度に1文字ずつ読み取るように強制する必要があります。

ここに作業バージョンがあります:

#!/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'それらはすべて同じ改行コードを表しているので、。しかし、それは\015or と同じではありません\r-これはキャリッジリターン(行の先頭に戻る)を表します。Linuxシステムでは、改行はを使用して表さ\nれますが、たとえばWindowsでは、\r\n代わりにのシーケンスで表されます。そのため、Windowsのテキストファイルを使用している場合は、を検索しても改行を検出できます\r


つまり、引用符で囲まれたエスケープシーケンスを\nバイト表現に変換しているため、見栄えが悪く、引用符で囲まれた改行をテストステートメントに配置する必要がありません。
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を返す出力があります。


\rコマンドの置換によって末尾の改行文字が削除されるため(これ"$(printf '\n\n\n\n\n')"は空の文字列です)、s を含まないファイルでは機能しません。
ステファンChazelas
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.