Ciągi przedrostków i przyrostków w każdym wierszu wyjściowym polecenia

17

Wystąpił problem podczas próby napisania skryptu Bash. Kiedy grepwyświetla, zwraca (zwykle) wiele wierszy. Chciałbym przedrostek i przyrostek do każdego z tych wierszy wyjściowych.

Chciałbym również zauważyć, że jestem potokiem lssię grep, jak:

ls | grep
SpecialBomb
źródło
2
Nie powinieneś parsować ls- to złe juju. Czy to musi być grep? Czy możesz podać przykładowy wynik?
Sobrique,
1
Co chcesz, aby skrypt działał, jeśli nazwa pliku zawiera nowy wiersz?
Tai Viinikka

Odpowiedzi:

27

Z sed:

ls | grep txt | sed 's/.*/prefix&suffix/'
Cyrus
źródło
3
Lub, sedbędąc nadzbiorem grep: ls | sed -n '/txt/s/.*/prefix&suffix/p'lubls | sed -n 's/.*txt.*/prefix&suffix/p'
Stéphane Chazelas,
@ StéphaneChazelas: Dziękuję za tę wskazówkę.
Cyrus
5

Z sed:

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

Ale zauważ, że cierpi to z powodu problemów z nazwami plików z liniami i wszystkimi innymi problemami z parsowaniem, lsco jest ogólnie złym pomysłem.

Z perlem

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

Uwaga - perl grepmoże przyjmować wzorzec - jak greppolecenie, ale możesz także wykonywać testy plików.

Na przykład

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

W grepdomyślnym iteratorze $_ustawiana jest bieżąca wartość elementu, dzięki czemu można zastosować sed/ grepstyl wyrażenia regularnego lub wykonać różne zadania w oparciu o $_.

Sobrique
źródło
Jak dołączyć zmienną jako sufiks / prefiks w pierwszym przykładzie, używając „sed ”?
SpecialBomb
Zmień cytaty i po prostu użyj ich.
Sobrique,
2

W tym przypadku GNU findpozwala robić wszystkie te rzeczy za jednym razem, eliminując potoki i potencjalnie kłopotliwe analizowanie ls:

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

( findoczywiście nie jest to dobry sposób na dowolną modyfikację wyników innych poleceń!)

Niektóre uwagi:

  • -maxdepth 1i -name [^.]*spraw, aby dopasowywanie nazw działało tak samo jak zwykły ls(lub ls .). Możesz użyć dowolnego globu w stylu powłoki, ale zauważ, że „*” będzie pasować do wiodącego „.” w nazwie † w przeciwieństwie do bash, więc [^.]*oznacza wszystko, co nie ma wiodącego „.”
  • MYPATTERN jest właściwym POSIX ERE (domyślny typ to Emacs, patrz tutaj ), ale musi pasować do całej nazwy pliku, więc użyj czegoś takiego jak .*thing.*zamiastthing
  • prawdopodobnie możesz po prostu użyć jednego z -name/ -regexzamiast obu (np. -regex "[^.]. MYPATTERN. "
  • -printfobsługuje wiele rzeczy , %njest bez ozdób nazwa pliku lub katalogu

(może to zależeć od twojej wersji find, sprawdź sekcję „ZGODNOŚĆ Z NORMAMI” na stronie podręcznika)

Jako możliwą alternatywę bez żadnych zewnętrznych programów wymaganych, bashma compgenktóre, między innymi, rozszerza globs, równoważna lsbez opcji:

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

To obsługuje nazwy plików z białymi znakami, w tym znaki nowej linii. compgen -G "*"powinien zapewniać takie same wyniki jak zwykły ls(ale należy pamiętać, że ls *jest to zupełnie inna rzecz). Nadal będziesz potrzebować grep, a to może rozwiązać problem, ale warto o nim wspomnieć.

pan. spuratic
źródło
0

seda findrozwiązania są kwestionowane, jeśli prefiks / sufiks zawierają znaki wyrażenia regularnego lub jeśli chcesz przekazać zmienną środowiskową (zamiast bezpośredniej wartości), xargs+ echomoże być bardziej odpowiednie tutaj.

Ze zmienną środowiskową:

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

Z wbudowanym:

ls | grep p | xargs -I % sh -c "echo `pwd`/%"
Lashgar
źródło