Yanıtlar:
Yapamazsın. Ed veya GNU sed veya perl kullanın ya da perde arkasında yaptıklarını yapın; içerik için yeni bir dosya oluşturun.
ed, taşınabilir:
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, yeni bir dosya oluşturma (önerilir, çünkü komut dosyanız kesintiye uğradıysa, tekrar çalıştırabilirsiniz):
cut -d , -f 1,3 <foo >foo.new &&
mv -f foo.new foo
cut, dosyanın yerinde değiştirilmesi (sahipliğini ve izinlerini korur foo, ancak kesintilere karşı korunması gerekir):
cp -f foo foo.old &&
cut -d , -f 1,3 <foo.old >foo &&
rm foo.old
cutTabanlı yöntemlerden birini kullanmanızı öneririm . Bu şekilde standart olmayan herhangi bir araca bağımlı olmazsınız, iş için en iyi aracı kullanabilir ve kesme sırasındaki davranışı kontrol edebilirsiniz.
cut -d , -f 1,3 foo > foo.new rm foo mv foo.new foo
rm foo. Ve aramamalısınız rm foo, çünkü mv foo.new fooatomik: eski sürümü kaldırır ve yeni sürümü aynı anda yerine koyar.
Moreutils Ubuntu (ve aynı zamanda paket debian ) adlı bir program var spongesıralama-de sorunu çözer.
Erkek süngerinden:
sünger standart girdiyi okur ve belirtilen dosyaya yazar. Kabuk yönlendirmesinden farklı olarak, sünger çıktı dosyasını açmadan önce tüm girdilerini emer. Bu, aynı dosyadan okunan ve aynı dosyaya yazılan boru hatlarının daraltılmasına izin verir.
Hangi gibi bir şey yapmanıza izin verir:
cut -d <delim> -f <fields> somefile | sponge somefile
POSIX Awk ile slurp kullanabilirsiniz:
cut -b1 file | awk 'BEGIN{RS="";getline<"-";print>ARGV[1]}' file
Çünkü Eh, cutokur daha az çıktı üretir, bunu yapabilirsiniz:
cut -c1 < file 1<> file
Yani, stdin'i filesalt okunur modda açık hale getirin ve stdout'u filekesmeden okuma + yazma modunda açık hale getirin ( <>).
Bu şekilde, cutdosyanın üzerine yazar. Ancak, dosyanın geri kalanına dokunulmaz. Örneğin, aşağıdakileri fileiçeriyorsa:
foo
bar
Çıktı:
f
b
bar
f\nb\nYerini almıştır foo\n, ama barhala var. Sonra dosyayı kısaltmanız gerekircut .
İle ksh93, komut başarılı olursa , dosya tanımlayıcısında çağrılması dışında , <>;işleci ile yapabilirsiniz . Yani:<>ftruncate()
cut -c1 < file 1<>; file
Diğer mermilerle, aşağıdakiler ftruncate()gibi başka yollarla yapmanız gerekir :
{ cut -c1 < file; perl -e 'truncate STDOUT, tell STDOUT';} 1<> file
ancak bunun için çağırmak perl, özellikle bu işi perlkolayca yapabileceğini göz önünde bulundurarak biraz abartılı olsa da cut:
perl -pi -e '$_ = substr($_, 0, 1)' file
Gerçek yerinde yeniden yazma içeren tüm yöntemlerde, işlem yarıda kesilirse, bozuk bir dosyaya sahip olacağınıza dikkat edin. Geçici bir ikinci dosya kullanmak bu sorunu önler.
.oldYerinde değişiklikler için yöntemden daha iyi ,echo "$(cut -d , -f 1,3 <foo)" > foo