man
หน้าไม่ให้ฉันหวังมาก แต่ฉันหวังว่ามันเป็นที่ไม่มีเอกสาร (และ / หรือ GNU เฉพาะ) คุณลักษณะ
man
หน้าไม่ให้ฉันหวังมาก แต่ฉันหวังว่ามันเป็นที่ไม่มีเอกสาร (และ / หรือ GNU เฉพาะ) คุณลักษณะ
คำตอบ:
คุณทำไม่ได้ ใช้ 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
มันเป็นอะตอมมิกมันจะลบเวอร์ชันเก่าออกและวางเวอร์ชันใหม่ไว้ในเวลาเดียวกัน
moreutilsแพคเกจจากอูบุนตู (และเดเบียน ) มีโปรแกรมที่เรียกว่าsponge
ซึ่งการจัดเรียงของยังแก้ปัญหาของคุณ
จากฟองน้ำมนุษย์:
ฟองน้ำอ่านอินพุตมาตรฐานและเขียนมันออกไปยังไฟล์ที่ระบุ แตกต่างจากการเปลี่ยนเส้นทางของเชลล์ฟองน้ำดูดซับอินพุตทั้งหมดก่อนที่จะเปิดไฟล์เอาต์พุต สิ่งนี้อนุญาตให้มีการวางท่อที่อ่านและเขียนไปยังไฟล์เดียวกัน
ซึ่งจะช่วยให้คุณทำสิ่งที่ชอบ:
cut -d <delim> -f <fields> somefile | sponge somefile
ฉันไม่คิดว่าเป็นไปได้ที่จะใช้cut
คนเดียว ฉันหามันไม่เจอในหน้า man หรือ info คุณสามารถทำอะไรบางอย่างเช่น
mytemp=$(mktemp) && cut -d" " -f1 file > $mytemp && mv $mytemp file
mktemp
ทำให้คุณเป็นไฟล์ชั่วคราวที่ค่อนข้างปลอดภัยที่คุณสามารถไปป์cut
เอาท์พุทเข้า
ลองเป็นกลุ่ม:
$ ex -s +'%!cut -c 1-10' -cxa file.txt
วิธีนี้จะแก้ไขไฟล์ในตำแหน่ง (ดังนั้นควรสำรองข้อมูลก่อน)
คุณสามารถใช้ slurp กับ POSIX Awk:
cut -b1 file | awk 'BEGIN{RS="";getline<"-";print>ARGV[1]}' file
เนื่องจากcut
ผลผลิตน้อยกว่าที่อ่านดังนั้นคุณสามารถ:
cut -c1 < file 1<> file
นั่นคือทำให้ stdin file
เปิดในโหมดอ่านอย่างเดียวและ stdout file
เปิดในโหมดอ่าน + เขียนโดยไม่มีการตัดทอน ( <>
)
ด้วยวิธีนี้cut
จะเขียนทับไฟล์ทับตัวเอง อย่างไรก็ตามมันจะทำให้ส่วนที่เหลือของไฟล์ไม่มีการแตะต้อง ตัวอย่างเช่นหากfile
มี:
foo
bar
ผลลัพธ์จะกลายเป็น:
f
b
bar
f\nb\n
ได้เปลี่ยนfoo\n
แต่bar
ยังคงมี คุณต้องตัดทอนไฟล์หลังจากcut
เสร็จสิ้น
ด้วยksh93
, คุณสามารถทำได้ด้วย<>;
โอเปอเรเตอร์ซึ่งทำหน้าที่เหมือน<>
ยกเว้นว่าถ้าคำสั่งสำเร็จ, ftruncate()
จะถูกเรียกบน file descriptor ดังนั้น:
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
ระวังด้วยวิธีการทั้งหมดที่เกี่ยวข้องกับการเขียนในสถานที่จริงถ้าการดำเนินการถูกขัดจังหวะกลางคันคุณจะพบไฟล์ที่เสียหาย การใช้ไฟล์ที่สองชั่วคราวหลีกเลี่ยงปัญหานี้
.old
วิธีการเปลี่ยนแปลงแบบแทนที่echo "$(cut -d , -f 1,3 <foo)" > foo