Reputation: 1848
I am trying to convert all files in a given directory with suffix ".foo" to files containing the same basename but with suffix modified to ".bar". I am able to do this with a shell script and a for loop, but I want to write a one-liner that will achieve the same goal.
Objective:
Input: *.foo
Output: *.bar
This is what I have tried:
find . -name "*.foo" | xargs -I {} mv {} `basename {} ".foo"`.bar
This is close but incorrect. Results:
Input: *.foo
Output: *.foo.bar
Any ideas on why the given suffix is not being recognized by basename? The quotes around ".foo" are dispensable and the results are the same if they are omitted.
Upvotes: 4
Views: 1657
Reputation: 1
Why don't you use "rename" instead of scripts or loops.
RHEL: rename foo bar .*foo
Debian: rename 's/foo/bar/' *.foo
Upvotes: -1
Reputation: 10582
Although basename
can work on file extensions, using the shell parameter expansion features is easier:
for file in *.foo; do mv "$file" "${file%.foo}.bar"; done
Your code with basename
doesn't work because the basename
is only run once, and then xargs just sees {}.bar
each time.
Upvotes: 4
Reputation: 136425
$ for f in *.foo; do echo mv $f ${f%foo}bar; done
mv a.foo a.bar
mv b.foo b.bar
Remove echo
when ready.
Upvotes: 1
Reputation: 9733
for file in *.foo ; do mv $file
echo $file | sed 's/\(.*\.\)foo/\1bar/'
; done
Example:
$ ls
1.foo 2.foo
$ for file in *.foo ; do mv $file `echo $file | sed 's/\(.*\.\)foo/\1bar/'` ; done
$ ls
1.bar 2.bar
$
Upvotes: 2