Create some test files. I've assumed your filenames have a single "." character:
mkdir foo
touch foo/one.txt foo/two.txt foo/three.txt
If you list the files (ll foo
) you'll get something like:
total 0
-rw-r--r-- 1 molomby staff 0B 21 Mar 21:49 one.txt
-rw-r--r-- 1 molomby staff 0B 21 Mar 21:49 three.txt
-rw-r--r-- 1 molomby staff 0B 21 Mar 21:49 two.txt
Now we're going to loop over the files and use some string manipulation to rename them.
for file in foo/*;
do
mv "${file}" "${file%%.*}-${file%%/*}.${file##*.}"
done
Lets unpack that a little.
- The first line itterates over the files matching the
foo/*
glob. Thefile
var will have a values likefoo/one.txt
, etc. - We're running a move command from the current file (
${file}
) to a new filename built out of parts:${file%%.*}
-> the file path, with everything after the "." removed (eg.foo/one
)-
-> a litteral "-" charactor${file%%/*}
-> the file path, with everything after the "/" removed (eg.foo
).
-> a litteral "." charactor${file##*.}
-> the file path, with everything before the "." removed (eg.txt
)
The commands are wrapped in quotes in case there are spaces in the filenames. So we end up running these commands:
mv "foo/one.txt" "foo/one-foo.txt"
mv "foo/three.txt" "foo/three-foo.txt"
mv "foo/two.txt" "foo/two-foo.txt"
If you listing the files again (ll foo
) you'll get:
total 0
-rw-r--r-- 1 molomby staff 0B 21 Mar 21:49 one-foo.txt
-rw-r--r-- 1 molomby staff 0B 21 Mar 21:49 three-foo.txt
-rw-r--r-- 1 molomby staff 0B 21 Mar 21:49 two-foo.txt
Why does
work
but not
It's to do with the string but I don't understand how to stop the manipulation going up so far?