ฉันพบปัญหาขณะพยายามเขียนสคริปต์ 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
/ grep
regex $_
สไตล์หรือดำเนินการความหลากหลายของงานขึ้นอยู่กับ
“
และเพียงใช้ 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
? และคุณสามารถให้ตัวอย่างผลลัพธ์