所定のファイルを「カット」して変更できますか?


回答:


14

できません。edまたはGNU sedまたはperlを使用するか、コンテンツの新しいファイルを作成するためにバックグラウンドで実行します。

ed、ポータブル:

ed foo <<EOF
1,$s/^\([^,]*\),\([^,]*\),\([^,]*\).*/\1,\3/
w
q
EOF

GNU sed

sed -i -e 's/^\([^,]*\),\([^,]*\),\([^,]*\).*/\1,\3/' foo

Perl:

perl -i -l -F, -pae 'print @F[1,3]' foo

cut、新しいファイルを作成します(スクリプトが中断された場合、再度実行できるため、推奨されます):

cut -d , -f 1,3 <foo >foo.new &&
mv -f foo.new foo

cut、ファイルを所定の場所に置き換えます(の所有権とアクセス許可は保持されますが、foo中断に対する保護が必要です):

cp -f foo foo.old &&
cut -d , -f 1,3 <foo.old >foo &&
rm foo.old

cutベースの方法のいずれかを使用することをお勧めします。そうすれば、非標準ツールに依存せず、ジ​​ョブに最適なツールを使用でき、割り込み時の動作を制御できます。


.oldインプレース変更の方法よりも優れていますecho "$(cut -d , -f 1,3 <foo)" > foo
-GypsyCosmonaut

1
@GypsyCosmonautいいえ、これは「より良い」ものではありません。もっと壊れやすいです。唯一の利点は、入力する時間が短くなることです。メソッドの主な問題は、入力ファイルの処理中または出力の書き込み中にエラーが発生すると、データが失われることです。また、バイナリデータでは機能しません。出力は最初のヌルバイトで切り捨てられます。テキストファイルであっても、ファイルの末尾から空の行を削除します。大きなファイルでは、データをシェルのメモリに文字列として保存する必要があるため、失敗する可能性があります(これが発生すると、データが失われることに注意してください)。
ジル「SO-停止されて悪」

oOおかげで、nullバイトに問題があるかもしれないとは知りませんでした
-GypsyCosmonaut

これはもっと簡単だと思います:cut -d , -f 1,3 foo > foo.new rm foo mv foo.new foo
LoMaPh

@LoMaPh確かに、古いファイルの名前を変更した理由はわかりません。新しいファイルの名前を変更するよりも利点はありません。また、stepは必要ないため、より簡単ですrm foo。アトミックrm fooであるため、呼び出すべきではありません。mv foo.new foo古いバージョンを削除し、同時に新しいバージョンを配置します。
ジル 'SO-悪であるのをやめる'

23

ubuntu(およびdebian)のmoreutilsパッケージにはと呼ばれるプログラムがあり、sort-ofも問題を解決します。sponge

マンスポンジから:

spongeは標準入力を読み取り、指定されたファイルに書き出します。シェルリダイレクトとは異なり、スポンジは出力ファイルを開く前にすべての入力を吸収します。これにより、同じファイルを読み書きするパイプラインを制限できます。

次のようなことができます:

cut -d <delim> -f <fields> somefile | sponge somefile

9

cut単独で使用できるとは思いません。マニュアルまたは情報ページで見つけることができませんでした。次のようなことができます

mytemp=$(mktemp) && cut -d" " -f1 file > $mytemp && mv $mytemp file

mktempcut出力をパイプすることができる比較的安全な一時ファイルになります。


1

vim-wayを試してください:

$ ex -s +'%!cut -c 1-10' -cxa file.txt

これにより、ファイルがその場で編集されます(最初にバックアップを実行します)。

またはgrepsedまたはを使用しますgawk



0

まあ、それcutはそれが読むよりも少ない出力を生成するので、あなたがすることができます:

cut -c1 < file 1<> file

つまり、stdin fileを読み取り専用モードでfile開き、stdout を切り捨てなしで読み取り+書き込みモードで開きます(<>)。

そうcutすれば、ファイル自体を上書きするだけです。ただし、ファイルの残りの部分は変更されません。たとえば、次がfile含まれる場合:

foo
bar

出力は次のようになります。

f
b
bar

f\nb\nを置き換えましfoo\nbarが、まだ存在しています。cut終了後にファイルを切り捨てる必要があります。

を使用ksh93すると、コマンドが成功した場合にファイル記述子で呼び出されることを除いて、<>;演算子を使用して実行できます。そう:<>ftruncate()

cut -c1 < file 1<>; file

他のシェルでは、次のftruncate()ような他の方法で行う必要があります。

{ cut -c1 < file; perl -e 'truncate STDOUT, tell STDOUT';} 1<> file

ただし、perlそのためだけに呼び出すのは少しやり過ぎです。特にperl、次cutのような仕事を簡単に行えることを考えると、

perl -pi -e '$_ = substr($_, 0, 1)' file

実際のインプレース書き換えを含むすべての方法で、操作が途中で中断されると、ファイルが破損することに注意してください。一時的な2番目のファイルを使用すると、この問題を回避できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.