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