Awalan dan akhiran string ke setiap baris output dari perintah

17

Saya mengalami masalah saat mencoba menulis skrip Bash. Ketika grepoutput, ia mengembalikan (biasanya) banyak baris. Saya ingin awalan dan sufiks sebuah string ke masing-masing jalur output ini.

Saya juga ingin untuk dicatat bahwa saya perpipaan lske grep, seperti:

ls | grep
SpecialBomb
sumber
2
Anda seharusnya tidak menguraikan ls- itu juju buruk. Juga, haruskah demikian grep? Dan bisakah Anda memberikan beberapa contoh output?
Sobrique
1
Apa yang ingin skrip Anda lakukan jika nama file berisi baris baru?
Tai Viinikka

Jawaban:

27

Dengan sed:

ls | grep txt | sed 's/.*/prefix&suffix/'
Cyrus
sumber
3
Atau, sedmenjadi superset dari grep: ls | sed -n '/txt/s/.*/prefix&suffix/p'atauls | sed -n 's/.*txt.*/prefix&suffix/p'
Stéphane Chazelas
@ StéphaneChazelas: Terima kasih atas petunjuk ini.
Cyrus
5

Dengan sed:

ls | grep pattern | sed -e 's/^/prefix/' -e 's/$/suffix/'

Tetapi perhatikan, ini mengalami masalah dengan nama file dengan umpan baris, dan semua masalah penguraian lsyang umumnya merupakan ide yang buruk.

Dengan perl

perl -e 'print "prefix".$_."suffix\n" for grep { m/somepattern/} glob "*"'

Catatan - perl grepdapat mengambil pola - seperti grepperintah, tetapi Anda juga dapat melakukan hal-hal seperti menerapkan tes file.

Misalnya

grep {-d} glob "*" #filters directories.
grep { (stat)[9] > time() - 60 } glob "*" #reads file mtime and compares. 

Dalam grepiterator default $_diatur ke nilai elemen saat ini, sehingga Anda dapat menerapkan sed/ grepstyle regex, atau melakukan berbagai tugas berdasarkan $_.

Sobrique
sumber
Bagaimana saya memasukkan variabel sebagai akhiran / awalan dalam contoh pertama Anda menggunakan ´sed´?
SpecialBomb
Ubah kutipan dan gunakan em.
Sobrique
2

Dalam hal ini, GNU findmemungkinkan Anda melakukan semua hal ini sekaligus, menghilangkan pipa dan kemungkinan penguraian ls:

find . -maxdepth 1 -name '[^.]*' \
  -regextype posix-extended -regex "MYPATTERN" \
  -printf 'SOMEPREFIX %f SOMESUFFIX\n'

( findtentu saja bukan cara yang baik untuk memodifikasi output dari perintah lain!)

Beberapa catatan:

  • -maxdepth 1dan -name [^.]*membuat pencocokan nama berfungsi sama dengan dataran ls(atau ls .). Anda dapat menggunakan gumpalan gaya-shell apa pun, tetapi perhatikan bahwa "*" akan cocok dengan yang pertama "." dalam nama tidak seperti bash, jadi [^.]*berarti apa pun yang tidak memiliki arahan "."
  • MYPATTERN adalah POSIX ERE yang tepat (tipe standarnya adalah Emacs, lihat di sini ), tetapi itu harus cocok dengan seluruh nama file jadi gunakan sesuatu seperti .*thing.*alih - alih hanyathing
  • Anda mungkin dapat menggunakan salah satu -name/ -regexbukan keduanya (mis. -regex "[^.]. MYPATTERN. "
  • -printfmendukung banyak hal , %nadalah file atau nama direktori tanpa hiasan

(ini dapat bergantung pada versi Anda find, periksa bagian "KINERJA STANDAR" pada halaman manual Anda)

Sebagai alternatif yang mungkin tanpa program eksternal yang diperlukan, bashmemiliki compgenyang, antara lain, memperluas gumpalan, setara lsdengan yang tanpa opsi:

compgen -P "someprefix>" -S "<somesuffix" -G "pattern"

Ini menangani nama file dengan spasi putih, termasuk baris baru. compgen -G "*"harus memberikan output yang sama dengan yang biasa ls(tetapi perhatikan bahwa itu ls *adalah hal yang sama sekali berbeda). Anda masih perlu grep, dan ini mungkin atau mungkin tidak menyelesaikan masalah, tetapi perlu disebutkan.

mr.spuratic
sumber
0

seddan findsolusi ditantang jika awalan / akhiran Anda menyertakan karakter kunci regex atau jika ingin meneruskan variabel lingkungan (bukan nilai langsung), xargs+ echomungkin lebih sesuai di sini.

Dengan variabel lingkungan:

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

Dengan sebaris:

ls | grep p | xargs -I % sh -c "echo `pwd`/%"
lashgar
sumber