วิธีการทำ 'หัว' และ 'หาง' ในอินพุตที่มีการ จำกัด ด้วย null ในทุบตี?


18

findคำสั่งสามารถส่งออกชื่อของไฟล์เป็นสตริงที่คั่นด้วย null (ถ้า-print0มีให้) และxargsสามารถใช้พวกเขาด้วยการ-0เปิดตัวเลือก แต่ในระหว่างมันเป็นเรื่องยากที่จะจัดการกับคอลเลกชันของไฟล์ - sortคำสั่งมี-zสวิทช์ที่ทำให้มันเป็นไปได้ที่จะจัดเรียงไฟล์เหล่านั้น แต่headและtailไม่ได้พวกเขา

ฉันจะทำheadและtailป้อนข้อมูลด้วยตัวคั่นที่ไม่มีค่าในวิธีที่สะดวกได้อย่างไร (ฉันสามารถสร้างสคริปต์ทับทิมสั้นและช้าได้เสมอ แต่ฉันหวังว่าอาจมีวิธีที่ดีกว่า)

คำตอบ:


21

GNU headและtailcoreutils ตั้งแต่ 8.25 มี-zตัวเลือกสำหรับสิ่งนั้น

ด้วยรุ่นที่เก่ากว่าหรือสำหรับระบบที่ไม่ใช่ GNU คุณสามารถลองและสลับ\0และ\n:

find ... -print0 |
  tr '\0\n' '\n\0' |
  head |
  tr '\0\n' '\n\0'

ทราบว่าบางheadการใช้งานที่ไม่สามารถรับมือกับตัวละคร NUL (และพวกเขากำลังไม่จำเป็นต้องโดย POSIX) แต่ที่พบการสนับสนุน-print0, headและระบบสาธารณูปโภคข้อความทั่วไปสนับสนุนตัวละคร NUL

คุณสามารถใช้ฟังก์ชั่นเพื่อตัดคำสั่งใด ๆ ระหว่างสองtrs:

nul_terminated() {
  tr '\0\n' '\n\0' | "$@" | tr '\0\n' '\n\0'
}

find ... -print0 | nul_terminated tail -n 12 | xargs -r0 ...

เก็บไว้ในใจว่าภายใต้nul_terminatedการ\0หมายถึงอักขระ newline ตัวอย่างเช่นหากต้องการแทนที่\nด้วย_:

find . -depth -name $'*\n*' -print0 | nul_terminated sed '
  p;h;s,.*/,,;s/\x0/_/g;H;g;s,[^/]*\n,,' | xargs -r0n2 mv

( \x0เป็นส่วนขยาย GNU ด้วย)

หากคุณต้องการเรียกใช้คำสั่งการกรองมากกว่าหนึ่งคำสั่งคุณสามารถทำได้:

find ... -print0 |
  nul_terminated cmd1 |
  nul_terminated cmd2 | xargs -r0 ...

แต่นั่นหมายถึงการรันtrคำสั่งซ้ำซ้อนสองสามคำ หรือคุณสามารถเรียกใช้:

find ... -print0 | nul_terminated eval 'cmd1 | cmd2' | xargs -r0 ...

2
สิ่งนี้ไม่ได้เอาชนะเหตุผลหลักที่ใช้\x0แทน\nการกำหนดค่าหรือไม่ (¹เพื่อให้คุณสามารถรับมือกับค่าที่อาจมี\n)
Thedward

@Thedward ไม่มีในทางที่-print0 | tr '\n\0' '\0\n'มีเส้น\0ที่เป็นตัวแทนของเส้นทางแฟ้มที่ตัวอักษรขึ้นบรรทัดใหม่ในพวกเขาได้รับการแปลง ดังนั้นหากคุณใช้บรรทัดแรกด้วยhead -n 1และแปลง\0s กลับไปเป็นบรรทัดใหม่ด้วยtr '\0\n' '\n\0'อีกครั้งคุณจะได้รับไฟล์พา ธ แรก NUL คั่นด้วยอักขระบรรทัดใหม่ที่ฝังตัว
Stéphane Chazelas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.