:
true
เป็นชื่ออีก ทั้งสองมีความ builtins เปลือกทุบตี แต่ไม่มีเพียง/bin/:
/bin/true
การเปลี่ยนเส้นทางขาออกทำให้เกิดเปลือกเพื่อไฟล์ด้วยopen(2)
O_CREAT|O_TRUNC
หากไม่มีการเขียนอะไรมันจะอยู่ที่ความยาวเป็นศูนย์
การนำทั้งสองชิ้นมารวมกัน:> file
เป็นสำนวนที่ใช้กันโดยทั่วไปในการตัดไฟล์ คนส่วนใหญ่จะพยายามทำให้มันแปลกที่ดูน้อยลงโดยการเขียน: >file
แม้ว่า
เมื่อคุณถามความคิดเห็นเกี่ยวกับบรรทัดที่ 2 ฉันจะเปลี่ยนความคิดเห็นของฉันเป็นคำตอบ (แม้ว่าคุณจะไม่ได้ถามคำถามนี้)
บรรทัดที่ 2 เป็นลูปที่อ่านบรรทัดจากotherfile
ลงในตัวแปรที่ตั้งชื่อบางตัว ร่างกายวนใช้echo
พิมพ์ด้วย;
ตัวคั่นแทนสิ่งที่พวกเขาเคยมีมาก่อนช่องว่าง file
ถูกปิดและเปิดใหม่ (สำหรับผนวก) แต่ละการวนซ้ำเนื่องจากการเปลี่ยนเส้นทางอยู่ในลูป การใช้while ...;do read -r ...;done <otherfile >file
จะดูดน้อยลงและหลีกเลี่ยงความต้องการตัดทอนไฟล์ก่อน read -r
ไม่กิน\
เป็นตัวหนี
การประมวลผลข้อความใน bash ค่อนข้างช้า ส่วนหนึ่งที่หลีกเลี่ยงไม่ได้: read
ต้องไปทีละหนึ่งไบต์ (การread(2)
เรียกระบบหนึ่งครั้งต่อไบต์) เพื่อหลีกเลี่ยงการแก้ไขปัญหาการสิ้นสุดของบรรทัด มันจะเป็นการดีกว่าถ้าใช้เครื่องมือที่เหมาะสมสำหรับงาน:
awk -vOFS=';' '{ print $1, $2, $4, $5, $3 }' -- otherfile >file
--
หมายความว่าสคริปต์ของคุณจะไม่ผิดเพี้ยนถ้าotherfile
ตั้งชื่ออย่างโง่--version
ๆ
การตั้งค่าตัวคั่นฟิลด์เอาต์พุตเป็น;
หมายความว่าคุณสามารถส่งผ่านหลาย ๆ ฟิลด์ตามที่ต้องการพิมพ์ได้ เชลล์read
กำหนดส่วนที่เหลือทั้งหมดของบรรทัดด้วยช่องว่างให้กับตัวแปรสุดท้าย แต่ไม่มีวิธีที่จะบอก awk ให้แยกออกเป็น 5 เท่านั้นถ้านั่นเป็นสิ่งสำคัญ Perl ทำให้การดำเนินการนี้เป็นเรื่องง่ายเนื่องจากsplit
สามารถใช้เขตข้อมูลสูงสุดได้ แต่จะช้ากว่าการเริ่มต้น awk มาก
จริงๆแล้วมันกลายเป็นว่าไม่ยากเพียง regex น่าเกลียดที่จะเขียน ในการรับส่วนที่เหลือของสายแทนที่จะเป็น$5
awk การวนลูปเหนือฟิลด์ยังคงสูญเสียช่องว่างดั้งเดิม แนวคิดที่ทำงานได้เป็นครั้งแรกของฉันคือการใช้gensub
บน$0
(ทั้งบรรทัด) เพื่อลบ 4 ฟิลด์แรก (เช่นที่ไม่ใช่ช่องว่างตามด้วยช่องว่าง) ออกจากทุกอย่างอื่น:
awk -vOFS=';' '{ tail = gensub("[[:space:]]*([^[:space:]]+[[:space:]]+){4}", "", 1); print $1, $2, $4, tail, $3 }' -- otherfile >file
ฉันเข้าใจถูกในการลองครั้งแรก แต่ความจริงที่ว่าฉันรู้สึกประทับใจกับตัวเองเพราะมันบอกอะไรบางอย่างเกี่ยวกับความสามารถในการอ่านของรหัส awk นั้น >. <
หมายเหตุว่ามันเหมือนprint
เป็นมาก่อน แต่มีในสถานที่ของtail
$5
echo 'A B c DD e f g f' |
awk -vOFS=\; '{ tail = gensub("[[:space:]]*([^[:space:]]+[[:space:]]+){4}", "", 1);
print $1, $2, $4, tail, $3 }'
A;B;DD;e f g f;c
มันจะน่าประทับใจมากขึ้นถ้าฉันสามารถคัดลอก / วางตัวอักษรและแสดงว่ามันผ่านมาในการส่งออก พิมพ์หนึ่งใน bash ด้วย ^ Q ctrl-Q หมายถึงการกดปุ่มกดถัดไปเป็นตัวอักษรเนื่องจากการแก้ไขเส้นสไตล์ emacs ของ bash นั้นเหมือนกับ emacs จริงสำหรับสิ่งนี้
http://mywiki.wooledge.org/BashFAQมีบางสิ่งที่มีประโยชน์เกี่ยวกับการเขียนสคริปต์ในรูปแบบที่จะไม่ทำลายไม่ว่าคุณจะใส่ข้อมูลหรือชื่อไฟล์ใดในสคริปต์
:>
ไม่ใช่ตัวดำเนินการเดียว อาจเข้าใจได้ง่ายกว่าถ้าคุณอ่าน: > file
แทน