Строки префикса и суффикса к каждой строке вывода из команды

17

Я столкнулся с проблемой, пытаясь написать сценарий Bash. Когда grepвыводит, он возвращает (обычно) много строк. Я хотел бы префикс и суффикс строки для каждой из этих строк вывода.

Я также хотел бы отметить , что я ТРУБОПРОВОДНЫЙ lsв grep, как:

ls | grep
SpecialBomb
источник
2
Не стоит разбирать ls- это плохо, джиу. Кроме того, это должно быть grep? И можете ли вы привести пример вывода?
Sobrique
1
Что вы хотите, чтобы ваш скрипт делал, если имя файла содержит новую строку?
Тай Вииникка

Ответы:

27

С помощью sed:

ls | grep txt | sed 's/.*/prefix&suffix/'
Кир
источник
3
Или, sedбудучи надмножеством grep: ls | sed -n '/txt/s/.*/prefix&suffix/p'илиls | sed -n 's/.*txt.*/prefix&suffix/p'
Стефан Шазелас
@ StéphaneChazelas: Спасибо за этот совет.
Сайрус
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итераторе по умолчанию $_установлено текущее значение элемента, поэтому вы можете применять регулярные выражения sed/ grepстиль или выполнять различные задачи на основе $_.

Sobrique
источник
Как бы я включил переменную в качестве суффикса / префикса в вашем первом примере, используя ´sed´?
SpecialBomb
Измените кавычки на и просто используйте их.
Sobrique
2

В этом случае GNU findпозволяет вам делать все эти вещи за один раз, устраняя каналы и потенциально проблемный анализ ls:

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

( findконечно, это не хороший способ произвольно изменить вывод других команд!)

Некоторые заметки:

  • -maxdepth 1и -name [^.]*заставить сопоставление имен работать так же, как обычный ls(или ls .). Вы можете использовать любой глобус в стиле оболочки, но учтите, что «*» будет соответствовать лидирующему «.» в имени † в отличие от bash, значит [^.]*означает что-либо, что не имеет лидирующего "."
  • MYPATTERN - это правильный POSIX ERE (тип по умолчанию - Emacs, см. Здесь ), но он должен соответствовать всему имени файла, поэтому используйте что-то вроде, .*thing.*а не простоthing
  • вы, вероятно, можете просто использовать один из -name/ -regexвместо обоих (например, -regex "[^.]. MYPATTERN. "
  • -printfподдерживает много вещей , %nявляется неукрашенным имя файла или каталога

(это может зависеть от вашей версии, findхотя, проверьте раздел «СТАНДАРТНОЕ СООТВЕТСТВИЕ» вашей справочной страницы)

В качестве возможной альтернативы без каких - либо внешних программ , необходимых, bashесть , compgenкоторые, помимо всего прочего, расширяет шарики, что эквивалентно lsбез опций:

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

Это обрабатывает имена файлов с пробелами, включая переводы строк. compgen -G "*"должен обеспечивать тот же вывод, что и обычный ls(но обратите внимание, что ls *это совсем другое). Вам все еще нужно grep, и это может или не может решить проблему, но стоит упомянуть.

mr.spuratic
источник
0

sedи findрешения оспариваются, если ваш префикс / суффикс включает ключевые символы регулярного выражения или если вы хотите передать переменную окружения (вместо непосредственного значения), xargs+ echoможет быть более подходящим здесь.

С переменной среды:

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

Со встроенным:

ls | grep p | xargs -I % sh -c "echo `pwd`/%"
lashgar
источник