ฉันพบปัญหาขณะพยายามเขียนสคริปต์ Bash เมื่อgrepผลลัพธ์มันจะส่งคืน (ปกติ) หลายบรรทัด ฉันต้องการคำนำหน้าและต่อท้ายสตริงกับแต่ละบรรทัดเอาต์พุตเหล่านี้
ฉันยังต้องการที่จะทราบว่าฉันท่อlsเข้าgrepเช่น:
ls | grep
ฉันพบปัญหาขณะพยายามเขียนสคริปต์ Bash เมื่อgrepผลลัพธ์มันจะส่งคืน (ปกติ) หลายบรรทัด ฉันต้องการคำนำหน้าและต่อท้ายสตริงกับแต่ละบรรทัดเอาต์พุตเหล่านี้
ฉันยังต้องการที่จะทราบว่าฉันท่อlsเข้าgrepเช่น:
ls | grep
คำตอบ:
ด้วยsed:
ls | grep pattern | sed -e 's/^/prefix/' -e 's/$/suffix/'
แต่โปรดทราบว่าสิ่งนี้ได้รับผลกระทบจากปัญหาเกี่ยวกับชื่อไฟล์ที่มีตัวดึงข้อมูลบรรทัดและปัญหาที่แตกต่างกันของการแยกวิเคราะห์lsซึ่งโดยทั่วไปเป็นความคิดที่ไม่ดี
ด้วย perl
perl -e 'print "prefix".$_."suffix\n" for grep { m/somepattern/} glob "*"'
หมายเหตุ - Perl grepสามารถใช้รูปแบบ - เช่นgrepคำสั่ง แต่คุณสามารถทำสิ่งต่าง ๆ เช่นใช้การทดสอบไฟล์
เช่น
grep {-d} glob "*" #filters directories.
grep { (stat)[9] > time() - 60 } glob "*" #reads file mtime and compares.
ภายในgrepเริ่มต้น iterator $_ถูกตั้งค่าให้ค่าองค์ประกอบในปัจจุบันเพื่อให้คุณสามารถใช้sed/ grepregex $_สไตล์หรือดำเนินการความหลากหลายของงานขึ้นอยู่กับ
“และเพียงใช้ em
ในกรณีนี้ GNU findช่วยให้คุณทำสิ่งเหล่านี้ทั้งหมดในครั้งเดียวการกำจัดท่อและการแยกวิเคราะห์ที่อาจลำบากls:
find . -maxdepth 1 -name '[^.]*' \
-regextype posix-extended -regex "MYPATTERN" \
-printf 'SOMEPREFIX %f SOMESUFFIX\n'
( findไม่ใช่วิธีที่ดีในการปรับเปลี่ยนเอาต์พุตของคำสั่งอื่นโดยพลการแน่นอน!)
หมายเหตุบางส่วน:
-maxdepth 1และ-name [^.]*ทำให้การจับคู่ชื่อทำงานเหมือนกับ Plain ls(หรือls .) คุณสามารถใช้รูปแบบเชลล์แบบใดก็ได้ แต่โปรดทราบว่า "*" จะตรงกับส่วนนำ "" ในชื่อ†ต่างbashกันดังนั้น[^.]*หมายถึงสิ่งใดก็ตามที่ไม่มีผู้นำ "".*thing.*แทนที่จะเป็นเพียงthing-name/ -regexแทนทั้งคู่ (เช่น -regex "[^.]. MYPATTERN. "-printfสนับสนุนจำนวนมากสิ่งที่ , %nเป็นไฟล์ตกแต่งหรือชื่อไดเรกทอรี† (สิ่งนี้ขึ้นอยู่กับเวอร์ชันของคุณ
findให้ตรวจสอบในส่วน "มาตรฐานการยืนยัน" ของหน้าคนของคุณ)
ในฐานะที่เป็นทางเลือกที่เป็นไปได้โดยไม่จำเป็นต้องใช้โปรแกรมภายนอกซึ่งbashมีcompgenสิ่งอื่น ๆ ที่ช่วยขยาย globs เทียบเท่าlsกับที่ไม่มีตัวเลือก:
compgen -P "someprefix>" -S "<somesuffix" -G "pattern"
วิธีนี้จะจัดการกับชื่อไฟล์ด้วยช่องว่างรวมถึงการขึ้นบรรทัดใหม่ compgen -G "*"ควรให้ผลลัพธ์เดียวกันกับแบบธรรมดาls(แต่ให้สังเกตว่าls *เป็นสิ่งที่แตกต่างอย่างสิ้นเชิง) คุณจะยังคงต้องการgrepและสิ่งนี้อาจหรือไม่อาจแก้ปัญหาได้ แต่ก็คุ้มค่าที่จะกล่าวถึง
sedและการfindแก้ปัญหาจะถูกท้าทายหากคำนำหน้า / คำต่อท้ายของคุณมีอักขระคีย์ regex หรือหากต้องการส่งผ่านตัวแปรสภาพแวดล้อม (แทนที่จะเป็นค่าปัจจุบัน) xargs+ echoอาจเหมาะสมกว่าที่นี่
ด้วยตัวแปรสภาพแวดล้อม:
ls | grep p | xargs -I % sh -c "echo $PATH/%"
ด้วย inline:
ls | grep p | xargs -I % sh -c "echo `pwd`/%"
lsมันเป็น juju ที่ไม่ดี นอกจากนี้ยังจะต้องมีgrep? และคุณสามารถให้ตัวอย่างผลลัพธ์