61

I have a large file with many scattered file paths that look like

lolsed_bulsh.png

I want to prepend these file names with an extended path like:

/full/path/lolsed_bullsh.png

I'm having a hard time matching and capturing these. currently i'm trying variations of:

cat myfile.txt| sed s/\(.+\)\.png/\/full\/path\/\1/g | ack /full/path

I think sed has some regex or capture group behavior I'm not understanding

kevzettler
  • 4,783
  • 15
  • 58
  • 103
  • BRE doesn't support one or more `+`. Use `..*` instead (if you need to make sure there is at least 1 character). – nhahtdh May 25 '15 at 04:45

3 Answers3

70

In your regex change + with *:

sed -E "s/(.*)\.png/\/full\/path\/\1/g" <<< "lolsed_bulsh.png"

It prints:

/full/path/lolsed_bulsh

NOTE: The non standard -E option is to avoid escaping ( and )

higuaro
  • 15,730
  • 4
  • 36
  • 43
  • 4
    The detail I missed is that first capture group is on `\1`, NOT `\0`, which appears to be the whole current line. – ThorSummoner Jun 08 '17 at 21:16
28

Save yourself some escaping by choosing a different separator (and -E option), for example:

cat myfile.txt | sed -E "s|(..*)\.png|/full/path/\1|g" | ack /full/path

Note that where supported, the -E option ensures ( and ) don't need escaping.

Top-Master
  • 7,611
  • 5
  • 39
  • 71
Cezariusz
  • 463
  • 8
  • 15
  • Thank you! Used this to automate force cache busting of all css files (example): `find . -type f -name "*.html" -exec sed -Ei "s|(css\/..*)\.css\"|\1\.css?v=$(date +%s)\"|g" {}` – HEADLESS_0NE Nov 29 '22 at 22:27
12

sed uses POSIX BRE, and BRE doesn't support one or more quantifier +. The quantifier + is only supported in POSIX ERE. However, POSIX sed uses BRE and has no option to switch to ERE.

Use ..* to simulate .+ if you want to maintain portability.

Or if you can assume that the code is always run on GNU sed, you can use GNU extension \+. Alternatively, you can also use the GNU extension -r flag to switch to POSIX ERE. The -E flag in higuaro's answer has been tagged for inclusion in POSIX.1 Issue 8, and exists in POSIX.1-202x Draft 1 (June 2020).

silkfire
  • 24,585
  • 15
  • 82
  • 105
nhahtdh
  • 55,989
  • 15
  • 126
  • 162
  • In GNU sed the `-r` invokes the `ERE` functionality however see [here](http://stackoverflow.com/questions/3139126/whats-the-difference-between-sed-e-and-sed-e) for further details. – potong May 25 '15 at 08:55