回答:
できません。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
ベースの方法のいずれかを使用することをお勧めします。そうすれば、非標準ツールに依存せず、ジョブに最適なツールを使用でき、割り込み時の動作を制御できます。
cut -d , -f 1,3 foo > foo.new
rm foo
mv foo.new foo
rm foo
。アトミックrm foo
であるため、呼び出すべきではありません。mv foo.new foo
古いバージョンを削除し、同時に新しいバージョンを配置します。
まあ、それcut
はそれが読むよりも少ない出力を生成するので、あなたがすることができます:
cut -c1 < file 1<> file
つまり、stdin file
を読み取り専用モードでfile
開き、stdout を切り捨てなしで読み取り+書き込みモードで開きます(<>
)。
そうcut
すれば、ファイル自体を上書きするだけです。ただし、ファイルの残りの部分は変更されません。たとえば、次がfile
含まれる場合:
foo
bar
出力は次のようになります。
f
b
bar
はf\nb\n
を置き換えましfoo\n
たbar
が、まだ存在しています。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番目のファイルを使用すると、この問題を回避できます。
.old
インプレース変更の方法よりも優れていますecho "$(cut -d , -f 1,3 <foo)" > foo