ファイルから一連の行を読み取り、各行を削除するにはどうすればよいですか?
明らかに私はこのように読むことができます:
while read -r line; do
echo $line
done < myfile.txt
しかし、これを行うと:
while read -r line; do
echo $line
sed '1d' myfile.txt
done < myfile.txt
最初の行だけが表示されます
行を読み取るエレガントな方法を探し、それを使って何かを実行してから、ファイルの次の行に移動する前にそれを削除します。
sed
を1回だけ呼び出してから、各行の反復で呼び出したいと思います。元のファイルを変更したい場合、sed
に-i(-in-place)オプションを追加できます。
unset n
while read -r line; do
echo $line
: $((n++))
done < myfile.txt
sed "1,$n d" myfile.txt
できるよ:
sed -n '$d;w file2' >file1 <<IN
$(cat file1; echo .)
IN
これは、file1のすべての行を同時に削除しながら、file1からfile2にすべての行を安全に書き込みます。シェルは中間の一時ファイルを安全に処理します。1つのバイトを作成する前に、一時ファイルを作成してファイルシステムから削除します。
sed
がファイル記述子を解放するとすぐ(at EOFまたはそれが終了したとき-どちらか早い方)ファイルは存在しなくなります。一般的なsed -i
オプションとは異なり、これは、sed
自体のクリーンアップに依存しません(処理が予期せず中断された場合は発生しない可能性があります)また、-i
オプションが意味するのと同じアクセス許可の矛盾を伴いません。
そして、アプリケーションはデモンストレーションのようにグローバルである必要はありません-行を元の行から削除するか、別の出力に選択的に書き込むことができます...
sed -n '$d;/pattern1/w file2
/pattern2/p' >file1 <<IN
$(cat file1; echo .)
IN
.../pattern2/
に一致するfile1の行だけがfile1に出力される方法と、/pattern1/
に一致する同じ行だけがw
rittenからfile2に出力される方法を示します。もちろん、他のsed
コマンドも同様に適用できます。
ただし、ほとんどのシェルでは、これがfile1からNULバイトを引き継がないことはおそらく注目に値します((sed
work)の場合はあまり問題になりません)-このようなことはzsh
で可能です。
ファイルがこのスニペットで正しく処理されたら、ファイルのすべての行を置き換えることができます(処理が失敗した場合は削除しないでください。必要に応じて再処理できます)。
while read; do
if some_command_worked_correctly; then
sed -i '1,1 d' file-to-read
fi
done < file-to-read