Change * .foo to * .bar on unix one-liner

I am trying to convert all files in a given directory with the suffix ".foo" to files containing the same base name, but with the suffix changed to ".bar". I can do this with a shell script and a for loop, but I want to write a single line that will achieve the same goal.

Goal:
Input: * .foo
Output: * .bar

Here is what I tried:

find . -name "*.foo" | xargs -I {} mv {} `basename {} ".foo"`.bar 

This is close, but false. Results:
Input: * .foo
Output: * .foo.bar

Any ideas on why this suffix is ​​not recognized by basename? The quotation marks around ".foo" do not fit, and the results are the same if they are omitted.

+4
source share
6 answers

Although basename can work with file extensions, it is easier to use shell parameter extension functions:

 for file in *.foo; do mv "$file" "${file%.foo}.bar"; done 

Your code with basename does not work, because basename run only once, and then xargs just sees {}.bar every time.

+4
source

for a file in * .foo; do mv $ file echo $file | sed 's/\(.*\.\)foo/\1bar/' 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 $ 
+2
source

for x in $ (find. -name "* .foo"); do mv $ x $ {x %% foo} bar; done

+1
source
 $ 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.

+1
source

If you installed mmv , you can do

 mmv \*.foo \#1.bar 

.

-1
source

Why don't you use "renaming" instead of scripts or loops.

RHEL: rename foo bar .*foo

Debian: rename 's/foo/bar/' *.foo

-1
source

All Articles