読み込み中に行が欠落している sed

読み込み中に行が欠落している sed

誰かがこれを説明できますか?

ファイルがあります:

cat listi.txt
sdfasdfsf123sadfasdf123
jlkjh2345ljkh245lkh4325
57hghf456ghf457gf467

ここでsedは最初の行を見逃しました。

while read line ; do sed 's/[^0-9]//g'; done < listi.txt 

23452454325
57456457467

ここで確認してください:

while read line ; do echo $line; done < listi.txt 

sdfasdfsf123sadfasdf123
jlkjh2345ljkh245lkh4325
57hghf456ghf457gf467

これはうまくいきますが、重複した気がし、sedがすべての行を通過すると思ったので、見逃した可能性があります。

while read line ; do echo $line | sed 's/[^0-9]//g'; done < listi.txt 

123123
23452454325
57456457467

なぜこれですか? bashの信頼を再取得しました。なぜならそれが私を疑わせたからです。

答え1

初期ループ:

while read line; do
    sed 's/[^0-9]//g'
done <listi.txt 

ここで何が起こるのかは、readファイルから来るループの入力ストリームから1行を読むことですlisti.txt。値は変数lineいくつかの注意事項とともに) 廃止予定です。

sedその後、入力ファイルに言及せずに呼び出しが行われます。つまり、sed標準入力ストリームからそのファイルを読み取ることになります。

標準入力ストリームはsedループから継承されるため、listi.txtファイルの終わりに達するまで2行目と他のすべての行を読み取り、処理します。

その後、ループはread再実行されますが、読み取る内容がなくなったため、呼び出しは失敗し、ループは終了します。

listi.txt上記の全体的な効果は、sed2行目から始まるファイルの処理中にファイルの最初の行を無視し、各行から数字以外の文字を削除して端末に出力することです。

sedすべての行に式を適用するには、listi.txt次を使用できます。

sed 's/[^0-9]//g' listi.txt

sedつまり、編集式が入力ファイルの各行にデフォルトで適用されるため、別々のシェルループを使用する必要はありません。

数値以外のすべての数値を削除するには、tr単一文字変換を実行するツールであるこの操作を実行することもできます。

tr -d -c '0-9\n' <listi.txt

これにより、入力から上記の文字セットの補数()の一部であるすべての文字が-d削除されます(;入力を行に分割する改行文字を保存できるため、ここに含まれます)。このビットはとして書くこともできます。これは現在のロケールのすべての数字と改行文字と一致します。-c0-9\n0-9\n[:digit:]\n

また関連:

関連情報