คำนำหน้าและสตริงต่อท้ายไปยังแต่ละบรรทัดออกจากคำสั่ง


17

ฉันพบปัญหาขณะพยายามเขียนสคริปต์ Bash เมื่อgrepผลลัพธ์มันจะส่งคืน (ปกติ) หลายบรรทัด ฉันต้องการคำนำหน้าและต่อท้ายสตริงกับแต่ละบรรทัดเอาต์พุตเหล่านี้

ฉันยังต้องการที่จะทราบว่าฉันท่อlsเข้าgrepเช่น:

ls | grep

2
คุณไม่ควรแยกlsมันเป็น juju ที่ไม่ดี นอกจากนี้ยังจะต้องมีgrep? และคุณสามารถให้ตัวอย่างผลลัพธ์
Sobrique

1
คุณต้องการให้สคริปต์ทำอะไรถ้าชื่อไฟล์มีบรรทัดใหม่
Tai Viinikka

คำตอบ:



5

ด้วย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 $_สไตล์หรือดำเนินการความหลากหลายของงานขึ้นอยู่กับ


ฉันจะรวมตัวแปรเป็นคำต่อท้าย / คำนำหน้าในตัวอย่างแรกของคุณโดยใช้´sed´ ได้อย่างไร
SpecialBomb

เปลี่ยนเครื่องหมายคำพูดเป็นและเพียงใช้ em
Sobrique

2

ในกรณีนี้ 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กันดังนั้น[^.]*หมายถึงสิ่งใดก็ตามที่ไม่มีผู้นำ ""
  • MYPATTERN เป็น POSIX ERE ที่เหมาะสม (ประเภทเริ่มต้นคือ Emacs ดูที่นี่ ) แต่จะต้องตรงกับชื่อไฟล์ทั้งหมดดังนั้นให้ใช้สิ่งที่ต้องการ.*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และสิ่งนี้อาจหรือไม่อาจแก้ปัญหาได้ แต่ก็คุ้มค่าที่จะกล่าวถึง


0

sedและการfindแก้ปัญหาจะถูกท้าทายหากคำนำหน้า / คำต่อท้ายของคุณมีอักขระคีย์ regex หรือหากต้องการส่งผ่านตัวแปรสภาพแวดล้อม (แทนที่จะเป็นค่าปัจจุบัน) xargs+ echoอาจเหมาะสมกว่าที่นี่

ด้วยตัวแปรสภาพแวดล้อม:

ls | grep p | xargs -I % sh -c "echo $PATH/%"

ด้วย inline:

ls | grep p | xargs -I % sh -c "echo `pwd`/%"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.