The man
halaman tidak memberikan banyak harapan, tapi aku berharap itu adalah didokumentasikan (dan / atau GNU-spesifik) fitur.
The man
halaman tidak memberikan banyak harapan, tapi aku berharap itu adalah didokumentasikan (dan / atau GNU-spesifik) fitur.
Jawaban:
Kamu tidak bisa Baik menggunakan ed atau GNU sed atau perl, atau melakukan apa yang mereka lakukan di belakang layar, yaitu membuat file baru untuk konten.
ed
, portabel:
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
, membuat file baru (disarankan, karena jika skrip Anda terganggu, Anda dapat menjalankannya lagi):
cut -d , -f 1,3 <foo >foo.new &&
mv -f foo.new foo
cut
, mengganti file pada tempatnya (mempertahankan kepemilikan dan izin foo
, tetapi membutuhkan perlindungan terhadap interupsi):
cp -f foo foo.old &&
cut -d , -f 1,3 <foo.old >foo &&
rm foo.old
Saya sarankan menggunakan salah satu cut
metode berbasis. Dengan begitu Anda tidak bergantung pada alat non-standar, Anda dapat menggunakan alat terbaik untuk pekerjaan itu, dan Anda mengontrol perilaku pada interupsi.
cut -d , -f 1,3 foo > foo.new
rm foo
mv foo.new foo
rm foo
. Dan Anda tidak boleh menelepon rm foo
, karena mv foo.new foo
bersifat atomik: menghapus versi lama dan menempatkan versi baru pada saat yang bersamaan.
The MoreUtils paket dari ubuntu (dan juga debian ) memiliki program yang disebut sponge
, yang semacam-of juga memecahkan masalah Anda.
Dari man sponge:
spons membaca input standar dan menuliskannya ke file yang ditentukan. Tidak seperti pengalihan shell, spons menyerap semua inputnya sebelum membuka file output. Ini memungkinkan pipa penyusun yang membaca dari dan menulis ke file yang sama.
Yang memungkinkan Anda melakukan sesuatu seperti:
cut -d <delim> -f <fields> somefile | sponge somefile
Saya tidak berpikir itu mungkin menggunakan cut
sendirian. Saya tidak dapat menemukannya di halaman manual atau info. Anda dapat melakukan sesuatu seperti
mytemp=$(mktemp) && cut -d" " -f1 file > $mytemp && mv $mytemp file
mktemp
membuat Anda menjadi file sementara yang relatif aman yang dapat Anda gunakan untuk mem-pipe cut
output.
Anda dapat menggunakan slurp dengan POSIX Awk:
cut -b1 file | awk 'BEGIN{RS="";getline<"-";print>ARGV[1]}' file
Nah, karena cut
menghasilkan output lebih sedikit daripada yang dibaca, Anda dapat melakukan:
cut -c1 < file 1<> file
Yaitu, buat stdin menjadi file
open dalam mode read-only dan stdout file
open dalam mode read + write tanpa pemotongan ( <>
).
Dengan begitu, cut
hanya akan menimpa file itu sendiri. Namun, itu akan membuat sisa file tidak tersentuh. Misalnya, jika file
mengandung:
foo
bar
Outputnya akan menjadi:
f
b
bar
The f\nb\n
telah menggantikan foo\n
, tapi bar
masih ada. Anda harus memotong file setelah cut
selesai.
Dengan ksh93
, Anda dapat melakukannya dengan <>;
operatornya yang bertindak seperti <>
kecuali bahwa jika perintah berhasil, ftruncate()
dipanggil pada deskriptor file. Begitu:
cut -c1 < file 1<>; file
Dengan kerang lain, Anda harus melakukannya ftruncate()
melalui beberapa cara lain seperti:
{ cut -c1 < file; perl -e 'truncate STDOUT, tell STDOUT';} 1<> file
meskipun memohon perl
hanya untuk itu sedikit berlebihan di sini terutama mengingat yang perl
dapat dengan mudah melakukan cut
pekerjaan seperti:
perl -pi -e '$_ = substr($_, 0, 1)' file
Hati-hati dengan semua metode yang melibatkan penulisan ulang di tempat yang sebenarnya, jika operasi terputus di tengah jalan, Anda akan berakhir dengan file yang rusak. Menggunakan file kedua sementara menghindari masalah ini.
.old
metode untuk perubahan di tempat,echo "$(cut -d , -f 1,3 <foo)" > foo