ファイルから行を読み取って削除する

ファイルから行を読み取って削除する

ファイルから一連の行を読み、次に各行を削除する方法は?

明らかに、次のように読むことができます。

while read -r line; do
echo $line
done < myfile.txt

しかし、これを行うと:

while read -r line; do
echo $line
sed '1d' myfile.txt
done < myfile.txt

私は最初の行だけを取得します

私は1行を読んで、その行に何かをした後、ファイルの次の行に移動する前に削除するエレガントな方法を探しています。

答え1

sedむしろ一度だけ呼び出してから、各行の繰り返しで呼び出すことをお勧めします。ソースファイルを変更するには追加できます。-私- 所定の位置に)オプションsed

unset n
while read -r line; do
  echo $line
  : $((n++))
done < myfile.txt
sed "1,$n d" myfile.txt

答え2

あなたはできます:

sed -n '$d;w file2' >file1 <<IN
$(cat file1; echo .)
IN

これにより、file1のすべての行を削除しながら、file1のすべての行をfile2に安全に書き込むことができます。シェルは中間の一時ファイルを安全に処理します。一時ファイルを作成し、シングルバイトを書き込む前にファイルシステムから削除します。

sedファイル記述子が解放されると(EOFまたは終了時 - 最初に来る時点)ファイルがまったく存在しません。一般的なオプションとは異なり、クリーニング自体sed -iに依存しません。sed(予期しない中断を処理した場合、これは発生しない可能性があります)-iまた、オプションで示唆するのと同じ権限の不一致は発生しません。

そして、説明したように、アプリケーションはグローバルである必要はありません。元のファイルから行を削除するか、オプションで別々の出力に書き込むことができます。

sed -n '$d;/pattern1/w file2
           /pattern2/p' >file1 <<IN
$(cat file1; echo .)
IN

... file1から一致する行のみを再度file1に印刷する方法と、/pattern2/file1から一致する行のみをfile2に書き込む/pattern1/方法を示しますwsedもちろん、他のコマンドも機能します。

しかし、ほとんどのシェルでは、file1からNULバイトを継承しないことに注意する価値があります。(これは一般的にsed職場では問題になりません)- そんなことが可能ですがzsh

答え3

ファイルが正しく処理されたら、ファイル内のすべての行を次のコードスニペットに置き換えることができます。処理が失敗しても削除せず、必要に応じて再処理できます。

while read; do
  if some_command_worked_correctly; then
    sed -i '1,1 d' file-to-read
  fi
done < file-to-read

関連情報