Bash: how to use first parameter of the command as a variable for other next parameters?


numerous times it happen that for example i want to duplicate file where the duplicate will only have different suffix, like:

cp "long_file - name here! ěščřžýáíé.ext" "../long_file - name here! ěščřžýáíé - backup.ext"

i would like to use first parameter as a variable for second one, like:

cp “long_file - name here! ěščřžýáíé.ext” “$1_backup”

(adding _backup suffix)

And what if i would like to use the incomplete name as the first parameter, like:
cp long_f* $1*_backup

What is the most simple way to do it please?

About copying a single file with long name and giving such copy an “incremented” name: there’s no simple way to perform what you’re asking in a shell, but a less complicated one is this:

f=$(echo "long_file - name here! ěščřžýáíé") ; cp "$f.ext" "$f - backup.ext"

If you want to copy multiple files and rename each one of them during the same process, and you want it all done in the shell, then you need to create a shell script, as explained here.

I’d however strongly recommend you to install the Thunar file manager instead, because it’s capable of bulk renaming files, i.e. you can use Thunar to create a duplicate (copy) of all desired files and then use Thunar’s bulk-renaming capabilities in order to rename all such duplicates at once (e.g. replace blablabla*-copy.ext for blablabla*_backup.ext).

If you happen to be running Linux in a console-only terminal (i.e. no GUI / no Desktop Environment), you may install and use Midnight Commander in order to perform bulk file renaming (it also performs bulk file copying). This program’s name in the shell is mc, and on Debian-based distros (such as Ubuntu and Mint) you install it by issuing this command:

sudo apt install mc -y

You therefore run Midnight Commander by issuing the command mc at the shell terminal. If you run e.g. mc /tmp then Midnight Commander will be started showing you the contents of /tmp. If however you just run mc, then Midnight Commander will be started showing you the current directory. If prior to running mc you want to know what is your current directory in the shell terminal, run pwd to print the working directory.


If I understand your question correctly, perhaps another possibility would be to use the following command using xargs and basename command. Please edit the bellow command example to set your destination directory for all *.backup files:

$ ls *.ext | xargs basename -s ext | xargs -I {} cp {}ext {}backup

Here is what you can expect:

Similarly, if you do not feel like to use xargs you can use bash for loop to do the same job. Same here, set your destination directory anywhere you see fit:

$ for i in *.ext; do cp $i ${i%.ext}.backup; done

What to expect:

As @Yuri already suggested, feel free to use the above commands as part of bash script in case you need something more robust to work with.

Hope this helps


1 Like

The information you want is in the bash manpage under the heading “Parameter Expansion”. What you specifically want in this situation is the “pattern substitution” feature: ${parameter/pattern/string}

Put the base file name in a variable, eg: fname="Lights-15x15 2.lights"

Then use the file name in your parameter:
cp "${fname}" "${fname/\.lights/_copy.lights}"

That’s a bit simplistic, but you can refine your regexp to meet your needs.

To do multiple files you can use a for loop:
for fname in *.lights; do
cp "${fname}" "${fname/\.lights/_copy.lights}";