ไพพ์คำสั่งหลังจาก xargs ไพพ์


38

HP-UX ***** B.11.23 U ia64 **** ใบอนุญาตผู้ใช้ไม่ จำกัด

find . -type d -name *log* | xargs ls -la

ให้ฉันชื่อไดเรกทอรี (คนที่มีlogอยู่ในชื่อไดเรกทอรี) ตามด้วยไฟล์ทั้งหมดในไดเรกทอรีนั้น

ไดเรกทอรี  /var/opt/SID/application_a/log/,  /var/opt/SID/application_b/log/,  /var/opt/SID/application_c/log/และอื่น ๆ ประกอบด้วยไฟล์บันทึก

ฉันต้องการเพียงสอง logfiles ล่าสุดที่จะแสดงตามคำสั่งซึ่งผมมักจะพบการใช้lsls -latr | tail -2

ผลลัพธ์จะต้องมีลักษณะเช่นนี้ ..

/var/opt/SID/application_a/log/
-rw-rw-rw-   1 user1    user1      59698 Jun 11  2013 log1
-rw-rw-rw-   1 user1    user1      59698 Jun 10  2013 log2
/var/opt/SID/application_b/log/
-rw-rw-rw-   1 user1    user1      59698 Jun 11  2013 log1
-rw-rw-rw-   1 user1    user1      59698 Jun 10  2013 log2
/var/opt/SID/application_c/log/
-rw-rw-rw-   1 user1    user1      59698 Jun 11  2013 log1
-rw-rw-rw-   1 user1    user1      59698 Jun 10  2013 log2

find . -type d -name *log* | xargs ls -la | tail -2ไม่ได้ให้ผลลัพธ์ด้านบน สิ่งที่ฉันได้รับคือรายการของสองไฟล์สุดท้ายของ find . -type d -name *log* | xargs ls -laคำสั่ง

ดังนั้นฉันสามารถไพพ์คำสั่งหลังจากไพพ์ได้xargsหรือไม่ ฉันจะค้นหาวิธีอื่นเพื่อรับรายการผลลัพธ์ของไฟล์ในรูปแบบข้างต้นได้อย่างไร

find . -type d -name *log* | xargs sh -c "ls -ltr | tail -10"

ให้รายชื่อไดเรกทอรีสิบชื่อในไดเรกทอรีปัจจุบันที่เกิดขึ้นกับฉัน/var/opt/SIDและนั่นก็ไม่ใช่สิ่งที่ฉันต้องการ


2
คุณควรอ้างอิง*log*มิฉะนั้นเชลล์จะขยาย
Anthon

โปรดทราบว่าsh -cคาดว่าชื่อคำสั่ง (พารามิเตอร์ 0) เป็นอาร์กิวเมนต์ที่สองดังนั้นคุณควรทำเสมอfind . -type d -name *log* | xargs sh -c "ls -ltr | tail -10" lstail(สังเกตlstailที่ท้ายซึ่งจะทำหน้าที่เป็น$0เชลล์ที่สร้างขึ้น) มิฉะนั้นผลลัพธ์แรกของคุณจะเติมบทบาทนั้นและไม่ได้ใช้งาน
Jonas

คำตอบ:


57

คุณเกือบจะอยู่ที่นั่นแล้ว ในคำสั่งสุดท้ายของคุณคุณสามารถใช้-Iเพื่อทำlsอย่างถูกต้อง

-I replace-str

    แทนที่การเกิดขึ้นของreplace-strในอาร์กิวเมนต์เริ่มต้นด้วยชื่อที่อ่านจากอินพุตมาตรฐาน นอกจากนี้ช่องว่างที่ไม่มีเครื่องหมายอัญประกาศจะไม่ยุติรายการอินพุต ตัวคั่นเป็นอักขระขึ้นบรรทัดใหม่แทน นัย-xและ-L 1.

ดังนั้นด้วย

find . -type d -name "*log*" | xargs -I {} sh -c "echo {}; ls -la {} | tail -2"

คุณจะechoพบ dir จากfindนั้นทำls | tailมัน


หา -type d -name " log " | xargs -I {} sh -c "echo {}; ls -ltr {} | grep -E \" file_in | file_out \ "| tail -5" ฉันใช้อันนี้
Anotherperson1 1

3
ฉันจะทำอย่างไรxargs -n 1 sh -c 'echo $0'
Ginhing

1
บน MacOS ทดแทนไม่ได้ทำงานอยู่ภายในคำสั่งยกมาเพื่อให้echo $0เป็นประโยชน์ (และเข้าใจมากขึ้น)
mpuncel

1
เพื่อให้ทำงานร่วมกับชื่อไฟล์ที่มีช่องว่างการใช้งาน-print0, xargs -0และหลบหนี{}เข้ามาในราคาคู่ภายในshสั่ง:find . -type d -name "*log*" -print0 | xargs -0 -I {} sh -c "echo \"{}\";ls -la \"{}\" | tail -2"
เบเน KOPPEL

ฉันใช้ "xargs -n 1 sh -c" echo \ $ 0 | $ func "` ถ้าฉันต้องการใช้ตัวแปร $ func
god


2

นอกเหนือจาก fredtantini และเป็นการชี้แจงทั่วไป (เนื่องจากเอกสารมีความสับสนเล็กน้อย):

xargs -I {}จะใช้ '{}' ตัวละครจากอินพุตมาตรฐานและแทนที่ด้วยสิ่งที่มาจากท่อ ซึ่งหมายความว่าคุณสามารถแทนที่{}ด้วยชุดอักขระใด ๆ (อาจจะเหมาะกับรสนิยมการเขียนโปรแกรมที่คุณต้องการ) ตัวอย่างเช่นxargs -I % sh -c "echo %" : หากคุณใช้งานxargs -I {}คุณสามารถแทนที่ด้วยเสมอxargs -iเพราะมันเป็นชวเลข

sh -cจะบอกทุบตีของคุณ / เปลือกที่จะอ่านคำสั่งต่อไปจากสตริงและไม่ได้มาจากการป้อนข้อมูลมาตรฐาน ดังนั้นการเขียนเทียบเท่ากับsh -c "echo something"echo something

xargs -I {} sh -c "echo {}"จะอ่านป้อนข้อมูลที่คุณสร้างขึ้นด้วยซึ่งเป็นsh -c echo {}เนื่องจากคุณบอกให้แทนที่{}ด้วยอาร์กิวเมนต์ที่คุณได้รับจากไปป์นั่นคือสิ่งที่จะเกิดขึ้น

คุณสามารถทดสอบสิ่งนี้ได้อย่างง่ายดายแม้ไม่มี piping เพียงแค่พิมพ์คำสั่งด้านบนในเทอร์มินัล สิ่งที่คุณเขียนต่อไปจะได้รับเอาต์พุตไปยังเทอร์มินัล (Ctrl-D เพื่อออก)

ในls -la {}คำสั่งสิ่งเดียวกันจะเกิดขึ้นอีกครั้ง {}จะถูกแทนที่ด้วยเนื้อหาของคำสั่งก่อนท่อ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.