Ударьте Одним Лайнером:скопировать template_*.txt в foo_*.txt?
-
09-06-2019 - |
Вопрос
Допустим, у меня есть три файла (template_ *.txt):
- template_x.txt
- template_y.txt
- template_z.txt
Я хочу скопировать их в три новых файла (foo_* .txt).
- foo_x.txt
- foo_y.txt
- foo_z.txt
Есть ли какой-нибудь простой способ сделать это с помощью одной команды, например
cp --enableAwesomeness template_*.txt foo_*.txt
Решение
for f in template_*.txt; do cp $f foo_${f#template_}; done
Другие советы
[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
Мой предпочтительный способ:
for f in template_*.txt
do
cp $f ${f/template/foo}
done
Способ "Я-не-помню-синтаксис-подстановки":
for i in x y z
do
cp template_$i foo_$
done
Это должно сработать:
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
Вероятно, ломается, если в именах ваших файлов есть странные символы.Удалите символ "-v", когда (если) вы будете уверены, что он работает надежно.
Команда mmv
(доступно в Debian или Финк или легко скомпилировать самостоятельно) был создан именно для этой задачи.При использовании простого решения Bash мне всегда приходится искать документацию о расширении переменных.Но mmv
намного проще в использовании, довольно близко к "потрясающему"!;-)
Вашим примером было бы:
mcp "template_*.txt" "foo_#1.txt"
mmv
может обрабатывать и более сложные шаблоны, и у него есть некоторые проверки работоспособности, например, он гарантирует, что ни один из файлов в целевом наборе не появится в исходном наборе (чтобы вы не могли случайно перезаписать файлы).
Я ничего не знаю в bash или на cp, но есть простые способы сделать что-то подобное, используя (например) perl-скрипт:
($op = shift) || die "Usage: rename perlexpr [filenames]\n";
for (@ARGV) {
$was = $_;
eval $op;
die $@ if $@;
rename($was,$_) unless $was eq $_;
}
Тогда:
rename s/template/foo/ *.txt
Еще один способ сделать это:
$ ls template_*.txt | sed -e 's/^template\(.*\)$/cp template\1 foo\1/' | ksh -sx
Я всегда был впечатлен ImageMagick преобразовать программа, которая делает то, что вы ожидаете, с форматами изображений:
$ convert rose.jpg rose.png
У него есть дочерняя программа, которая позволяет выполнять пакетные преобразования:
$ mogrify -format png *.jpg
Очевидно, что они ограничены преобразованиями изображений, но у них есть интересные интерфейсы командной строки.