1

I use this following sed command for display names of files with a specific form:

ls -1 *|sed 's/^\(.*\).png/\1\/\1,/g'

If I have two files named BOH_Contour.png and BOV_Web.png, I obtain

BOH_Contour/BOH_Contour,
BOV_Web/BOV_Web,

Now I want to remove all _ in the second part of this result and to obtain

BOH_Contour/BOHContour,
BOV_Web/BOVWeb,

How can I do this?

jimmij
  • 47,140
Guuk
  • 895

4 Answers4

4

That's typically where you'd use the hold space:

ls | sed '
  /\.png$/!d; # discard everything but lines ending in .png
  s///;       # remove that .png
  h;          # store on the hold space
  s/_//g;     # remove underscores
  H;          # append (with a newline) to the hold space
  g;          # retrieve that hold space
  s|\n|/|;    # substitute the newline with a /
  s/$/,/;     # add that extra comma.'
  • Thank you. Your command works also on names with several underscores. With the comma at the end: ls| sed '/\.png$/!d;s///;h;s/_//g;H;g;s|\n|/|;s/$/,/'. – Guuk Jan 20 '15 at 13:48
0

Just add another expression to sed after ;, eg:

sed 's/^\(.*\).png/\1\/\1,/g;s,/\(.*\)_,/\1,'

But keep in mind that parsing ls command is not a good habit.

jimmij
  • 47,140
0

Possible it helps:

ls -1 *|sed 's/^\(.*\).png/\1\/\1,/g ; : 1 ; s|_\([^/]*$\)|\1|; t 1'

Or if only 1 _ in file name

ls -1 *|sed 's/^\(.*\).png/\1\/\1,/g ; s|_||2'
Costas
  • 14,916
0

If all names contain one underscore, then just match the two parts of the name separately. You probably don't want the replacement anywhere in the line, just at the end of the file name, so lose the g modifier.

ls | sed 's/^\(.*\)_\(.*\)\.png$/\1_\2\/\1\2,/'

By the way, ls -1 is equivalent to ls when not used interactively. ls * is not equivalent to ls, the main difference being that if the current directory contains subdirectories then ls lists the entries in the current directory whereas ls * lists the entries that aren't subdirectories plus the content of all subdirectories. Given that this is hardly ever useful, you presumably meant ls.

If you want to remove all underscores no matter how many there are, while it's possible to use sed, it's rather clearer in awk.

ls | awk 'sub(/\.png$/, "") {$0 = $0 "/" gsub(/_/, "", $0) ","} 1'

Alternatively, you can use a shell loop.

for x in *; do
  case $x in
    *.png) x=${x%.png}; printf '%s/\n' "$x"; printf '%s,\n' "$x" | tr -d _;;
  esac
done