file1のパターンに一致する行を削除し、削除された行をfile2に保存します。

file1のパターンに一致する行を削除し、削除された行をfile2に保存します。

これがあり、file1パターンに一致する行を削除する必要があります。しかし、削除された行を別のfile2

sed    '/zz/!d' file1 > file2
sed -i '/zz/d' file1

これらのコマンドを1つにまとめる方法はありますか?

それとも、よりエレガントな方法はありますか?

答え1

GNU Sedをチェックしてください。

sed -ni '/zz/!{p;b};w file2' file1

フラグはこの順序で行わなければなりません-ni

説明:dコマンドを使用してスクリプトを停止するのではなくフラグ(自動)を設定し、コマンド(現在のパターンスペースを印刷)を使用して-nテンプレートと一致しない行を作成し、スクリプトの最後に移動します。パターンと一致する行は、パターン空間をファイルに書き込むコマンドに到達します。pbw

答え2

perl -pi -e 'select( /zz/ ? STDOUT : ARGVOUT )' file1 > file2

-ifile1 の内部編集を処理します。-pPerlプログラムを実行した後、行を印刷します。プログラムがすべきことは、出力位置を選択することだけです。この場合、これは?:select stdoutを使用して達成できますARGVOUT(これはまさにこれが-i使用されることです)。

答え3

何もない場合:

awk '/zz/{print >> "file2"; next} 1' file1 > tmp && mv tmp file1

一時ファイルを明示的に生成したくない場合は、次を使用してください。GNU awk:

gawk -i inplace '/zz/{print >> "file2"; next} 1' file1

追加する代わりに切り取りたい場合は、に>>変更してください。>file2

また見なさい:awkの「1」が現在行を印刷するのはなぜですか?

答え4

perlそのフラグと一緒に使用-iし、一致する行を標準出力に印刷してファイルにリダイレクトできます。

$ cat file1
asdasd
baba zzbabab
asdasd
sadkzzpasdad

$ perl -i -ne 'if(/zz/){ print STDOUT } else{ print }' file1 > file2

You could rewrite the above via a string form of eval where we construct
 the above piece of perl code based on presence of zz:

$ perl -i -ne 'eval "print ".qw[STDOUT][!/zz/]' file1 > file2

$ cat file1
asdasd
asdasd

$ cat file2 
baba zzbabab
sadkzzpasdad

Perlのもう一つのアプローチは次のとおりです。

$ perl -pi -e 'print(STDOUT),s/.*//s if /zz/' file1 > file2
  • 自動印刷モードの使用-p
  • zzラインを標準出力として印刷し、パターンを介してファイル1に書き戻したときに消去します-i

関連情報