Patrick McElhaney
Patrick McElhaney

Reputation: 59301

Bash One Liner: copy template_*.txt to foo_*.txt?

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

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

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

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

Upvotes: 9

Views: 852

Answers (8)

Roberto Bonvallet
Roberto Bonvallet

Reputation: 33359

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

Upvotes: 3

Blair Conrad
Blair Conrad

Reputation: 241980

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

Upvotes: 1

Bruno De Fraine
Bruno De Fraine

Reputation: 47346

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).

Upvotes: 1

Chris Conway
Chris Conway

Reputation: 56019

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

Upvotes: 11

Jon Ericson
Jon Ericson

Reputation: 21525

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.

Upvotes: 0

Matt McMinn
Matt McMinn

Reputation: 16311

[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

Upvotes: 3

Chris Bartow
Chris Bartow

Reputation: 15121

This should work:

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

Upvotes: 2

pauldoo
pauldoo

Reputation: 18635

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.

Upvotes: 1

Related Questions