แปลงบรรทัดใหม่เป็นตัวคั่น null เมื่อใช้ tail


20

ฉันจะเปลี่ยนผลลัพธ์จากtailการใช้บรรทัดที่สิ้นสุดด้วย null แทนการขึ้นบรรทัดใหม่ได้อย่างไร

คำถามของฉันคล้ายกับคำถามนี้: จะทำอย่างไร "หัว" และ "หาง" บนอินพุตที่มีการคั่นด้วย null ในทุบตี? แต่สิ่งที่ฉันต้องการทำมีดังนี้:

tail -f myFile.txt | xargs -i0 myCmd {} "arg1" "arg2"

ฉันไม่ได้ใช้findและใช้ไม่ได้-print0

ทั้งหมดนี้เพื่อหลีกเลี่ยงข้อผิดพลาดที่เกิดขึ้นใน xargs:

xargs: unmatched double quote;
    by default quotes are special to xargs unless you use the -0 option

คำตอบ:


26

หากคุณต้องการ 10 บรรทัดสุดท้าย:

tail myFile.txt | tr '\n' '\0' | xargs -r0i myCmd {} arg1 arg2

แต่ด้วย GNU xargsคุณสามารถตั้งค่าตัวคั่นเป็นบรรทัดใหม่ด้วย:

tail myFile.txt | xargs -ri -d '\n' myCmd {} arg1 arg2

( -0ย่อมาจาก-d '\0')

กระนั้นคุณก็สามารถหลบหนีตัวละครทุกตัวได้อย่างง่ายดาย:

tail myFile.txt | sed 's/./\\&/g' | xargs -I{} myCmd {} arg1 arg2

หรืออ้างแต่ละบรรทัด:

tail myFile.txt | sed 's/"/"\\""/g;s/.*/"&"/' | xargs -I{} myCmd {} arg1 arg2

หากคุณต้องการ 10 ระเบียน NUL คั่นล่าสุดmyFile.txt( แต่ก็ไม่คิดว่าจะเป็นไฟล์ข้อความ), คุณจะต้องแปลง\nไป\0ก่อนที่จะเรียกtailซึ่งจะหมายถึงไฟล์จะต้องได้รับอย่างเต็มที่อ่าน:

tr '\n\0' '\0\n' < myFile.txt |
  tail |
  tr '\n\0' '\0\n' |
  xargs -r0i myCmd {} arg1 arg2

แก้ไข (ตั้งแต่คุณเปลี่ยนtailไปtail -fในคำถามของคุณ):

tail -fคนสุดท้ายที่ดังกล่าวข้างต้นเห็นได้ชัดไม่ทำให้ความรู้สึก

xargs -d '\n'หนึ่งจะทำงาน แต่สำหรับคนอื่น ๆ คุณจะมีปัญหาบัฟเฟอร์ ใน:

tail -f myFile.txt | tr '\n' '\0' | xargs -r0i myCmd {} arg1 arg2

trบัฟเฟอร์เอาต์พุตเมื่อไม่ได้ไปที่เทอร์มินัล (ที่นี่ไปป์) IE จะไม่เขียนอะไรเลยจนกว่าจะมีบัฟเฟอร์เต็ม (เช่น 8kiB) ของข้อมูลในการเขียน ซึ่งหมายความว่าmyCmdจะถูกเรียกเป็นชุด

ในระบบของกนูหรือ FreeBSD คุณสามารถปรับเปลี่ยนพฤติกรรมของบัฟเฟอร์trที่มีstdbufคำสั่ง:

tail -f myFile.txt | stdbuf -o0 tr '\n' '\0' |
  xargs -r0i myCmd {} arg1 arg2

จริง ๆ แล้วฉันตั้งใจจะใช้ตัวเลือก -f ที่หางซึ่งพิมพ์บรรทัดอย่างต่อเนื่องเมื่อพวกเขาเข้ามาฉันไม่คิดว่ามันจะสำคัญ แต่เห็นได้ชัดว่ามันเป็นเช่นนั้น ด้วยอ็อพชัน -f โซลูชันของคุณจะไม่ทำงาน
ลาร์ส

tail -f myFile.txt | xargs -r0i -d '\n' myCmd "{}" "||" "||"ดูเหมือนว่าจะทำงาน! ขอบคุณ
ลาร์ส

@ ลาร์สขออภัย-iตัวเลือกใช้อาร์กิวเมนต์ที่เป็นทางเลือกดังนั้น-i0จะไม่ทำงาน พวกเขาทั้งหมดทำงานกับควรtail -fยกเว้นคนสุดท้าย แต่ระวังว่าเพราะบัฟเฟอร์จะมีการหน่วงเวลาก่อนที่จะได้รับการป้อนข้อมูลจากxargs trคุณสามารถเปลี่ยนที่โดยทำงานแทนstdbuf -o0 tr '\n' '\0' tr '\n' '\0'
Stéphane Chazelas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.