bitmvr
bitmvr

Reputation: 129

Convert last hyphen in filename using BASH

I've been tasked with a major file rename project. Some of these files that I'll be renaming contain multiple hyphens. I need to swap the last hyphen in the name to an underscore in order for the files to be renamed to our new naming convention.

Can anyone explain to me why the last hyphen not being replaced with an underscore in the test code below?

#!/bin/bash

image_name="i-need-the-last-hyphen-removed.psd"

echo -e "Normal: ${image_name}"
echo "Changed: ${image_name/%-/_}"

The output I am looking for should mimic the following:

Normal: i-need-the-last-hyphen-removed.psd
Changed: i-need-the-last-hyphen_removed.psd

The script logic was created by following documentation found here: http://tldp.org/LDP/abs/html/string-manipulation.html

I've tried escaping the hypen but that was not fruitful. I've given up, this will prove to be the most elegant solution versus using SED and/or BASH_REMATCH solutons I was working with in the past.

Any help would be great. Thank you in advance.

Upvotes: 0

Views: 311

Answers (4)

josifoski
josifoski

Reputation: 1726

I'll suggest using rename tool for this kind of tasks. It's sed pattern similar.

rename 's/(.*)-/$1_/' *.psd  

Since .* is greedy, that way last '-' will be catched, where (.*) is captured in group. Right part will not be changed.

With *.psd you will catch all psd files in current folder

Upvotes: 2

bitmvr
bitmvr

Reputation: 129

Huge thanks to @alex-p for the following suggestion. As I originally stated I didn't want to use SED or BASH_REMATCH or any other complex REGEX. This worked flawlessly.

echo "${image_name%-}_${image_name##-}"

Upvotes: 1

Eugeniu Rosca
Eugeniu Rosca

Reputation: 5305

${image_name/%-/_}" would only work if the - was the very termination/suffix of the $image_name (like e.g. in mystring-).

Try using sed:

$> echo i-need-the-last-hyphen-removed.psd | sed -r 's/-([^-]*$)/_\1/'
i-need-the-last-hyphen_removed.psd

Upvotes: 0

Rakholiya Jenish
Rakholiya Jenish

Reputation: 3223

You can do it using sed as:

sed -r "s/(.*)-(.*)/\1_\2/"

This will have two captured group (1. before last - 2. after last -)which will be concatenated with _ Or

sed -r "s/-([^-]*$)/_\1/"

This will have one captured group which will replace - with _ and then the captured group will be concatenated at last.

Upvotes: 0

Related Questions