รวมคำสั่ง unix หลายคำสั่งไว้ในที่เดียว


9

ฉันต้องการค้นหาบันทึกอีเมลของเราเพื่อหาที่อยู่อีเมลที่เฉพาะเจาะจง เราเก็บไฟล์ปัจจุบันชื่อmaillogรวมถึงไฟล์. bz2 มูลค่าหนึ่งสัปดาห์ในโฟลเดอร์เดียวกัน ขณะนี้ฉันใช้คำสั่งต่อไปนี้เพื่อค้นหาไฟล์:

grep person@domain.com maillog
bzgrep person@domain.com *.bz2

มีวิธีรวมgrepและbzgrepคำสั่งเป็นผลลัพธ์เดียวหรือไม่ ด้วยวิธีนี้ฉันสามารถไปป์ไลน์ผลลัพธ์ที่รวมเข้ากับอีเมลหรือไฟล์เดียว

คำตอบ:


24

อีกวิธีคือ

{ grep ...; bzgrep ...;} >file

&&มีปัญหาที่bzgrepจะไม่ทำงานหากgrepล้มเหลว

หมายเหตุพื้นที่ที่จำเป็นหลังจากวงเล็บปีกกาเปิดและเครื่องหมายอัฒภาคหลังจากคำสั่งสุดท้าย หรือคุณสามารถใช้ไวยากรณ์ย่อย (วงเล็บแทนวงเล็บปีกกา) ซึ่งไม่ใช่เรื่องพิถีพิถัน:

(grep ...; bzgrep ...) >file

+1 สำหรับเชลล์วัตถุประสงค์ทั่วไปที่ดีที่สุดสำหรับปัญหานี้ การจัดกลุ่มเชลล์เป็นคุณลักษณะที่ใช้งานไม่ได้โดยทั่วไป
Phil Hollenback

2
คุณไม่ได้หมายถึง()แทนที่จะเป็น{}เหรอ?
Ehtesh Choudhury

บน linux arch ใช้งานได้()แต่ไม่ใช่{}ทั้งสองวิธี +1 เพราะนี่คือสิ่งที่ฉันต้องการ!
Chris Magnuson

11

bzgrep เริ่มต้นที่ grep ปกติโดยอัตโนมัติหากไฟล์ไม่บีบอัด bzip ดังนั้นต่อไปนี้ควรจะเพียงพอ:

bzgrep person@domain.com maillog *bz2 | mail -s "logs yay" someuser@blah

โอ้แน่นอนว่านี่คือGNU Parallel solution ของฉันเช่นกัน:

parallel -m bzgrep person@domain.com ::: maillog* *bz2 | mail -s "logs yay" someuser@blah

ซึ่งอาจเร็วกว่ามากหากคุณตรวจสอบไฟล์จำนวนมาก


2

นี่เป็นอีกวิธีในการทำ (สมมติว่าคุณกำลังใช้ bash ซึ่งคุณอาจเป็น):

cat <(bzgrep ...) <(grep ...)

ที่นี่ทุบตีให้อาหารเอาท์พุทของคำสั่ง bzgrep และ grep เป็นแมวอย่างชัดเจนราวกับว่าพวกเขาเป็นไฟล์ (และพวกเขาอยู่ภายใต้ประทุนรายละเอียดใน url ที่ด้านล่าง)

ในกรณีของคุณโดยเฉพาะฉันขอแนะนำวิธีแก้ปัญหาของ Phil แต่สิ่งที่กล่าวมาข้างต้นเป็นเคล็ดลับที่ดีในการเก็บไว้ในกระเป๋า

หากคุณสนใจคุณสามารถอ่านเพิ่มเติมได้ที่นี่: http://www.tldp.org/LDP/abs/html/process-sub.html


อาใช่คำตอบที่ยอมรับได้สำหรับ 'คุณจะแตกต่างเอาท์พุทของกระบวนการที่สอง' ได้อย่างไร เคล็ดลับที่ดีที่จะรู้
Phil Hollenback

1

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

คุณสามารถใช้คำสั่งผสม:

{ grep ...; bzgrep ...; } >file

.. หรือ subshells (หมายเหตุวงเล็บแทนวงเล็บปีกกา):

(grep ...; bzgrep ...) >file

.. เพื่อจัดกลุ่มคำสั่ง วิธีการ subshell มีไวยากรณ์ที่ดีกว่า (การให้อภัยที่ไม่มีช่องว่างมากขึ้นและอนุญาตให้คุณละเว้นเซมิโคลอนสุดท้าย) แต่มันจะใช้กระบวนการใหม่หรือ "เสแสร้ง" โดยให้คำสั่งทำงานในสภาพแวดล้อมที่ทำความสะอาด ทั้งสองมีข้อดีขึ้นอยู่กับสิ่งที่คุณต้องการทำซึ่งไม่สำคัญที่นี่ แต่คุ้มค่าที่จะมองหาถ้าคุณต้องการความเชี่ยวชาญมากขึ้นกับเชลล์

หมายเหตุ: คุณสามารถใช้ pipelining กับลูกเล่นเหล่านี้ด้วยดังนั้นคุณสามารถทำสิ่งนี้:

{ grep ...; bzgrep ...; } | less

PS ถ้าคุณไม่สนใจเกี่ยวกับการสั่งซื้อของการแข่งขันในการส่งออกรวมของคุณคุณสามารถใช้เป็นหนึ่งเดียวระหว่างสองคำสั่งเช่นดังนั้น:& { grep ... & bzgrep ...; }จากนั้นทั้งสองคำสั่งทำงานพร้อมกันคือได้รับการเปิดตัวและเปลือกทำให้มันอยู่ในพื้นหลังแล้วเปลือกจะทำงานgrep bzgrep( แต่มีข้อแม้ขนาดเล็กด้วยที่มีคำอธิบายที่เกี่ยวข้องกับการเปลี่ยนเส้นทางของไฟล์และไฟล์สตรีมบัฟเฟอร์อาจก่อให้เกิดเป็นส่วนเล็ก ๆ ของบรรทัดในไฟล์ที่ส่งออกที่จะได้รับการแยก / mangled: ไม่ว่าคุณจะเห็นนี้จะขึ้นอยู่กับวิธีการของคุณgrep, bzgrepและlibc stdio.hฟังก์ชั่นจะดำเนินการ. ในการใช้งานมากที่สุดผมเชื่อว่าท่อคำสั่งก่อนที่จะเปลี่ยนเส้นทางไปยังไฟล์ที่จะหลีกเลี่ยงปัญหาที่เกิดขึ้นเพื่อให้คุณสามารถทำ{ foo & bar; } | cat - >fileเป็นวิธีแก้ปัญหา.)


0

คุณสามารถผูกคำสั่งพร้อมกับ && เพื่อให้คุณเรียกใช้แต่ละคำสั่ง

นอกจากนี้คุณยังสามารถเพิ่ม >> textfile.txt ที่ส่วนท้ายของแต่ละคำสั่งและให้ผลลัพธ์ที่ส่งถึงไฟล์จากนั้นส่งไฟล์นั้นออกมา


2
ตามที่ geekosaur กล่าวไว้ && ไม่ควรใช้ที่นี่เนื่องจากค่าส่งคืนของ grep ขึ้นอยู่กับว่าพบสิ่งนั้นหรือไม่ หากคุณทำเช่นgrep ... && bzgrep ...นั้นหาก grep ไม่พบเพลงจะส่งคืนความล้มเหลวและคำสั่งจะหยุดทำงาน >>เป็นความคิดที่ดีซึ่งแตกต่างจาก>มันจะเพิ่มผลลัพธ์ไปยังจุดสิ้นสุดของไฟล์ที่มีอยู่
DerfK

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