มันไม่ทำงาน สิ่งนี้สามารถทำได้ในการค้นหา? หรือฉันต้องการ xargs
find -name 'file_*' -follow -type f -exec zcat {} \| agrep -dEOE 'grep' \;
มันไม่ทำงาน สิ่งนี้สามารถทำได้ในการค้นหา? หรือฉันต้องการ xargs
find -name 'file_*' -follow -type f -exec zcat {} \| agrep -dEOE 'grep' \;
คำตอบ:
งานของการตีความสัญลักษณ์ไปป์เป็นคำสั่งเพื่อรันหลายกระบวนการและไพพ์เอาต์พุตของกระบวนการหนึ่งไปยังอินพุตของกระบวนการอื่นเป็นความรับผิดชอบของเชลล์ (/ bin / sh หรือเทียบเท่า)
ในตัวอย่างของคุณคุณสามารถเลือกที่จะใช้เปลือกระดับบนสุดของคุณเพื่อดำเนินการท่อดังนี้:
find -name 'file_*' -follow -type f -exec zcat {} \; | agrep -dEOE 'grep'
ในแง่ของประสิทธิภาพผลลัพธ์นี้มีค่าใช้จ่ายในการเรียกใช้การค้นหาหนึ่งการเรียกใช้ zcat จำนวนมากและการเรียกใช้ agrep หนึ่งครั้ง
สิ่งนี้จะส่งผลให้เกิดกระบวนการ agrep เพียงอันเดียวซึ่งจะเกิดขึ้นซึ่งจะประมวลผลเอาต์พุตทั้งหมดที่เกิดจากการเรียกใช้ zcat จำนวนมาก
หากคุณมีเหตุผลบางอย่างที่ต้องการเรียกใช้ agrep หลายครั้งคุณสามารถทำได้:
find . -name 'file_*' -follow -type f \
-printf "zcat %p | agrep -dEOE 'grep'\n" | sh
สิ่งนี้จะสร้างรายการคำสั่งโดยใช้ไพพ์เพื่อดำเนินการจากนั้นส่งคำสั่งเหล่านี้ไปยังเชลล์ใหม่เพื่อดำเนินการจริง (การละเว้น "| sh" เป็นวิธีที่ดีในการดีบักหรือดำเนินการบรรทัดคำสั่งแบบแห้ง)
ในแง่ของประสิทธิภาพผลลัพธ์นี้มีค่าใช้จ่ายการเรียกใช้การค้นหาหนึ่งการเรียกใช้ SH หนึ่งครั้งการเรียกใช้ zcat จำนวนมากและการเรียกใช้ agrep จำนวนมาก
โซลูชันที่มีประสิทธิภาพมากที่สุดในแง่ของจำนวนการเรียกใช้คำสั่งคือคำแนะนำจาก Paul Tomblin:
find . -name "file_*" -follow -type f -print0 | xargs -0 zcat | agrep -dEOE 'grep'
... ซึ่งมีค่าใช้จ่ายในการร้องขอการค้นหาหนึ่งการเรียกใช้ xargs หนึ่งการเรียกใช้ zcat สองสามครั้งและการเรียกใช้ agrep หนึ่งครั้ง
-exec sh -c "… | … " \;
:
การแก้ปัญหาเป็นเรื่องง่าย: ดำเนินการผ่าน sh
... -exec sh -c "zcat {} | agrep -dEOE 'grep' " \;
-c
ตัวเลือก มิฉะนั้นคุณจะได้รับNo such file or directory
ข้อความแสดงข้อผิดพลาดที่ทำให้งง
find -type f -name '*.mdds' -exec sh -c "echo {} | sed -e 's/_[0-9]\+//g' | xargs mv {}" \;
find . -name "file_*" -follow -type f -print0 | xargs -0 zcat | agrep -dEOE 'grep'
คุณยังสามารถไพพ์ไปยังwhile
ลูปที่สามารถดำเนินการหลายอย่างกับไฟล์ที่find
ตั้งอยู่ ดังนั้นนี่คือสิ่งที่มองหาที่jar
เก็บถาวรสำหรับไฟล์คลาส java ที่กำหนดในโฟลเดอร์ที่มี distro jar
ไฟล์ขนาดใหญ่
find /usr/lib/eclipse/plugins -type f -name \*.jar | while read jar; do echo $jar; jar tf $jar | fgrep IObservableList ; done
จุดสำคัญคือการwhile
วนรอบมีหลายคำสั่งอ้างอิงชื่อไฟล์ที่ส่งผ่านคั่นด้วยเซมิโคลอนและคำสั่งเหล่านี้สามารถรวมไปป์ ดังนั้นในตัวอย่างนั้นฉันสะท้อนชื่อของไฟล์ที่ตรงกันจากนั้นแสดงรายการสิ่งที่อยู่ในการกรองไฟล์เก็บถาวรสำหรับชื่อคลาสที่ระบุ ผลลัพธ์ดูเหมือนว่า:
/usr/lib/eclipse/plugins/org.eclipse.core.contenttype.source_3.4.1.R35x_v20090826-0451.jar /usr/lib/eclipse/plugins/org.eclipse.core.databinding.observable_1.2.0.M20090902-0800 .jar org / eclipse / core / databinding / ติดตามได้ / list / IObservableList .class /usr/lib/eclipse/plugins/org.eclipse.search.source_3.5.1.r351_v20090708-0800.jar / usr / lib / eclipse org.eclipse.jdt.apt.core.source_3.3.202.R35x_v20091130-2300.jar /usr/lib/eclipse/plugins/org.eclipse.cvs.source_1.0.400.v201002111343.jar / usr / lib / eclipse / ปลั๊กอิน / org.eclipse.help.appserver_3.1.400.v20090429_1800.jar
ในเปลือกทุบตีของฉัน (xubuntu10.04 / xfce) มันจะทำให้ classname ที่จับคู่เป็นตัวหนาเป็นfgrep
ไฮไลต์สตริงที่ตรงกัน; ทำให้ง่ายต่อการค้นหารายการjar
ไฟล์หลายร้อยไฟล์ที่ถูกค้นหาและดูรายการที่ตรงกันได้อย่างง่ายดาย
บน windows คุณสามารถทำสิ่งเดียวกันกับ:
for /R %j in (*.jar) do @echo %j & @jar tf %j | findstr IObservableList
โปรดทราบว่าในหน้าต่างตัวคั่นคำสั่งคือ '&' ไม่ '; และ '@' จะระงับเสียงสะท้อนของคำสั่งเพื่อให้เอาต์พุตที่เป็นระเบียบเหมือนกับ linux ค้นหาเอาต์พุตด้านบน แม้ว่าfindstr
จะไม่ทำให้สตริงที่ตรงกันเป็นตัวหนาดังนั้นคุณต้องมองเข้าไปที่เอาต์พุตให้ใกล้ขึ้นเพื่อดูชื่อคลาสที่ตรงกัน ปรากฎว่าคำสั่ง windows 'for' รู้ถึงเทคนิคบางอย่างเช่นการวนลูปผ่านไฟล์ข้อความ ...
สนุก
ฉันพบว่าการรันคำสั่ง string shell (sh -c) ทำงานได้ดีที่สุดตัวอย่างเช่น:
find -name 'file_*' -follow -type f -exec bash -c "zcat \"{}\" | agrep -dEOE 'grep'" \;
หากคุณกำลังมองหาทางเลือกง่ายๆสิ่งนี้สามารถทำได้โดยใช้การวนซ้ำ:
for i in $(find -name 'file_*' -follow -type f);do zcat $i | agrep -dEOE 'grep');done
หรือแบบฟอร์มทั่วไปที่เข้าใจง่ายขึ้น:
for i in $(YOUR_FIND_COMMAND);do YOUR_EXEC_COMMAND_AND_PIPES );done
และแทนที่ {} โดย $ i ใน YOUR_EXEC_COMMAND_AND_PIPES