誰かがこれを説明できますか?
ファイルがあります:
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
上記の全体的な効果は、sed
2行目から始まるファイルの処理中にファイルの最初の行を無視し、各行から数字以外の文字を削除して端末に出力することです。
sed
すべての行に式を適用するには、listi.txt
次を使用できます。
sed 's/[^0-9]//g' listi.txt
sed
つまり、編集式が入力ファイルの各行にデフォルトで適用されるため、別々のシェルループを使用する必要はありません。
数値以外のすべての数値を削除するには、tr
単一文字変換を実行するツールであるこの操作を実行することもできます。
tr -d -c '0-9\n' <listi.txt
これにより、入力から上記の文字セットの補数()の一部であるすべての文字が-d
削除されます(;入力を行に分割する改行文字を保存できるため、ここに含まれます)。このビットはとして書くこともできます。これは現在のロケールのすべての数字と改行文字と一致します。-c
0-9\n
0-9\n
[:digit:]\n
また関連: