Prefix and suffix strings to each output line from command

With sed:

ls | grep txt | sed 's/.*/prefix&suffix/'

With sed:

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

But note, this suffers from problems with filenames with line feeds, and all the assorted problems of parsing ls which is generally a bad idea.

With perl

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

Note - perl grep can take a pattern - like the grep command, but you can also do things like apply file tests.

E.g.

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

Within grep the default iterator $_ is set to the current element value, so you can apply sed/grep style regex, or perform a variety of tasks based on $_.


In this case GNU find lets you do all these things in one go, eliminating pipes and potentially troublesome parsing of ls:

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

(find is not a good way to arbitrarily modify the output of other commands, of course!)

Some notes:

  • -maxdepth 1 and -name [^.]* make name matching work the same as a plain ls (or ls .). You can use any shell-style glob, but note that "*" will match a leading "." in a name unlike bash, so [^.]* means anything that doesn't have a leading "."
  • MYPATTERN is a proper POSIX ERE (default type is Emacs, see here), but it must match the entire filename so use something like .*thing.* instead of just thing
  • you can probably just use one of -name/-regex instead of both (e.g. -regex "[^.].MYPATTERN."
  • -printf supports lots of things, %n is the unadorned file or directory name

(this can depend on your version of find though, check the "STANDARDS CONFORMANCE" section of your man page)

As a possible alternative with no external programs required, bash has compgen which, among other things, expands globs, equivalent to an ls with no options:

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

This handles filenames with whitespace, including newlines. compgen -G "*" should provide the same output as a plain ls (but note that ls * is a different thing entirely). You'll still need grep, and this may or may not solve the problem, but it's worth a mention.