Question

Say I have three files (template_*.txt):

  • template_x.txt
  • template_y.txt
  • template_z.txt

I want to copy them to three new files (foo_*.txt).

  • foo_x.txt
  • foo_y.txt
  • foo_z.txt

Is there some simple way to do that with one command, e.g.

cp --enableAwesomeness template_*.txt foo_*.txt

Was it helpful?

Solution

for f in template_*.txt; do cp $f foo_${f#template_}; done

OTHER TIPS

[01:22 PM] matt@Lunchbox:~/tmp/ba$
ls
template_x.txt  template_y.txt  template_z.txt

[01:22 PM] matt@Lunchbox:~/tmp/ba$
for i in template_*.txt ; do mv $i foo${i:8}; done

[01:22 PM] matt@Lunchbox:~/tmp/ba$
ls
foo_x.txt  foo_y.txt  foo_z.txt

My preferred way:

for f in template_*.txt
do
  cp $f ${f/template/foo}
done

The "I-don't-remember-the-substitution-syntax" way:

for i in x y z
do
  cp template_$i foo_$
done

This should work:

for file in template_*.txt ; do cp $file `echo $file | sed 's/template_\(.*\)/foo_\1/'` ; done
for i in template_*.txt; do cp -v "$i" "`echo $i | sed 's%^template_%foo_%'`"; done

Probably breaks if your filenames have funky characters in them. Remove the '-v' when (if) you get confidence that it works reliably.

The command mmv (available in Debian or Fink or easy to compile yourself) was created precisely for this task. With the plain Bash solution, I always have to look up the documentation about variable expansion. But mmv is much simpler to use, quite close to "awesomeness"! ;-)

Your example would be:

mcp "template_*.txt" "foo_#1.txt"

mmv can handle more complex patterns as well and it has some sanity checks, for example, it will make sure none of the files in the destination set appear in the source set (so you can't accidentally overwrite files).

I don't know of anything in bash or on cp, but there are simple ways to do this sort of thing using (for example) a perl script:

($op = shift) || die "Usage: rename perlexpr [filenames]\n";

for (@ARGV) {
    $was = $_;
    eval $op;
    die $@ if $@;
    rename($was,$_) unless $was eq $_;
}

Then:

rename s/template/foo/ *.txt

Yet another way to do it:

$ ls template_*.txt | sed -e 's/^template\(.*\)$/cp template\1 foo\1/' | ksh -sx

I've always been impressed with the ImageMagick convert program that does what you expect with image formats:

$ convert rose.jpg rose.png

It has a sister program that allows batch conversions:

$ mogrify -format png *.jpg

Obviously these are limited to image conversions, but they have interesting command line interfaces.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top