Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a simple bash script:

input_dir="`dirname $1`/`basename $1`/"
output_dir="`dirname $2`/`basename $2`/"
echo -n `rename "-f" "'s/.*([0-9]{11}_[0-9]{11}).*\.(.*$)/$1.$2/'" "$output_dir"*.$ext`

The problem is that it does not work because the match groups $N conflict with command line arguments to the script. How can I solve this?

share|improve this question
up vote 1 down vote accepted

In general, you can stop the shell from interpreting a metacharacter by escaping it with a backslash (\). So, you can prevent all the $ in the rename argument from being expanded by prepending a backslash:

echo -n `rename "-f" "'s/.*([0-9]{11}_[0-9]{11}).*\.(.*\$)/\$1.\$2/'" "$output_dir"*.$ext`

In this particular case, since the string s/.*([0-9]...$2/ does not need any shell-level substitutions (the whole point of your question is how to prevent them), you could just enclose it in single quotes (') which prevents all shell processing:

echo -n `rename "-f" 's/.*([0-9]{11}_[0-9]{11}).*\.(.*$)/$1.$2/' "$output_dir"*.$ext`

(Note that you do not need quotes around the -f, since it does not contain any shell metacharacters.)

share|improve this answer

Regarding the question you asked: use single quotes around a literal string where you don't want any substitution to happen. If you need a single quote in that string, type it as '\''.

echo -n `rename "-f" 's/.*([0-9]{11}_[0-9]{11}).*\.(.*$)/$1.$2/' "$output_dir"*.$ext`

There's something else wrong with your code. The result of a variable susbtitution like $1 and $2 or a command substitution like `rename …` is parsed by the shell, it performs word splitting and globbing on the result. Always use double quotes around variable substitutions and command substitutions unless you know you need to omit them. Furthermore, don't use backquotes, as they handle nested quotes in tricky and shell-dependent ways. All shells outside museums support the saner $(…) syntax. Also you need a -- on the invocations of dirname and basename, in case $1 or $2 starts with a - and thus looks like an option.

input_dir="$(dirname -- "$1")/$(basename -- "$1")/"
output_dir="$(dirname -- "$2")/$(basename -- "$2"/)"
ext="$3"    # here it would be ok to omit the quotes, but if you're unsure of the rules, put the quotes in
echo -n "$(rename -f 's/.*([0-9]{11}_[0-9]{11}).*\.(.*)$/$1.$2/' "$output_dir"*".$ext")"

As an aside, I don't understand what you're trying to achieve here. The way you're invoking it, rename doesn't produce any output.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.