これがあり、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
テンプレートと一致しない行を作成し、スクリプトの最後に移動します。パターンと一致する行は、パターン空間をファイルに書き込むコマンドに到達します。p
b
w
答え2
perl -pi -e 'select( /zz/ ? STDOUT : ARGVOUT )' file1 > file2
-i
file1 の内部編集を処理します。-p
Perlプログラムを実行した後、行を印刷します。プログラムがすべきことは、出力位置を選択することだけです。この場合、これは?:
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
。