6

Say I need to move the file /etc/dir1/dir2/dir3/a.out to /etc/dir1/dir2/dir3/b.out

Typing the whole path twice is tedious, and going to the directory might not be ideal. Is there a way to do such a move without retyping the directory?

On a related question (that I suspect has the same solution). Say I want to move a file someverybigfilename.png to somereallybigfilename.png. Is there a way to accomplish that without retyping the name?

(I know I can use a script. But does mv support some such thing natively?)

In short: how can I use move to partially alter/alter just a part of a filename? How to do a small change like extension?

4
  • Make a function in your bashrc file that takes 3 args, path, file1, and file2, and just build up paths to both files internally. Id post an answer but i am not able to do so on phone. I will later unless somebody does it before me Mar 22, 2017 at 17:41
  • 4
    The first is simple - using brace expansion: mv /etc/dir1/dir2/dir3/{a.out,b.out} or even mv /etc/dir1/dir2/dir3/{a,b}.out Mar 22, 2017 at 18:00
  • @steeldriver please post as an answer :) Mar 22, 2017 at 18:08
  • @George done ... now that I figured out Pt 2 ;) Mar 22, 2017 at 18:12

4 Answers 4

13

In the first case, if you are using bash, you can use brace expansion:

mv /etc/dir1/dir2/dir3/{a.out,b.out} 

or even

mv /etc/dir1/dir2/dir3/{a,b}.out

In the second case you could use brace expansion again:

mv some{very,really}bigfilename.png

Or (although it doesn't really save much typing) you could use Bash history expansion as follows:

$ mv someverybigfilename.png !#$:s/very/really
mv someverybigfilename.png somereallybigfilename.png
4
  • mv some{very,really}bigfilename.png seems to work as well
    – josinalvo
    Mar 22, 2017 at 19:21
  • @josinalvo good point Mar 22, 2017 at 19:25
  • Fascinating. Can you recommend link to read up on braces and where/how they are typically used for substitutions? Mar 22, 2017 at 19:39
  • @WinEunuuchs2Unix: See the links I added in my edit. Mar 22, 2017 at 20:23
2

either

cd /etc/dir1/dir2/dir3/
mv a.out b.out

or

make a script like

#!/bin/bash
dir_Path="/etc/dir1/dir2/dir3/"

mv $dir_Path\a.out $dir_Path\b.out

exit

and to rename:

#!/bin/bash
dir_Path="/etc/dir1/dir2/dir3/"
name_part="bigfile.png"
cd $dir_Path
mv some$name_part somereally$name_part

exit
2

If the path is the same I don't see the reason why not entering in the folder.

You could save the path with pushd or came back with cd -

Example:

luca@elite:~$ pushd dir1/dir2/dir3/
~/tmp/dir1/dir2/dir3 ~/tmp
luca@elite:~/dir1/dir2/dir3$ mv a.out b.out
luca@elite:~/dir1/dir2/dir3$ popd
~/tmp
luca@elite:~$ 

or

luca@elite:~$ cd dir1/dir2/dir3/
luca@elite:~/dir1/dir2/dir3$ mv b.out a.out
luca@elite:~/dir1/dir2/dir3$ cd -
luca@elite:~$ 

About the filename the only thing that came to my mind is to store it in a variable..

1

There's several ways to approach this. One could be via function defined in ~/.bashrc file.

pmv(){
    mv "$1"/"$2" "$1"/"$3"
}

The pmv function then would take 3 arguments. Path to directory, source file, and destination file. For instance:

$ ls testdir
self_test.sh*  test.wxg
$ pmv ./testdir  test.wxg  test2.wxg                                                                                     
$ ls testdir                                                                                                             
self_test.sh*  test2.wx

Notice that in this function we join directory path and file path with slash, thus when path to directory is given as command-line argument, there shouldn't be a trailing slash at the end. We can, however, improve the function definition using bash's parameter expansion, which will then allow us to use either /path/to/dir or /path/to/dir/:

pmv(){
    mv "${1%/}"/"$2" "${1%/}"/"$3"
}

On a related question (that I suspect has the same solution). Say I want to move a file someverybigfilename.png to somereallybigfilename.png. Is there a way to accomplish that without retyping the name?

Effectively,no, there is no way to do that with mv alone. Even steeldriver's and mine solutions for first part of your question make use of bash's features, not mv's. More advanced renaming manipulations, such as in your case inserting text into filename, should be done with prename where you use perl regular expressions to dynamically rename files.

$ touch someverybigfilename.png

$ prename 's/very/really/' someverybigfilename.png                                                                       

$ ls somereallybigfilename.png                                                                                           
somereallybigfilename.png

Not the answer you're looking for? Browse other questions tagged .