um loop for
:
for f in *.c; do cp -- "$f" "$OTHERDIR/old#$f"; done
Costumo adicionar a opção -v
a cp
para que eu possa acompanhar o progresso.
Eu quero copiar e renomear vários arquivos de código-fonte em um diretório.
Eu posso copiar assim:
$ cp *.c $OTHERDIR
Mas quero dar um prefixo a todos os nomes de arquivo:
file.c --> old#file.c
Como posso fazer isso em um passo?
Você pode usar a globalização de conchas:
for f in *.c; do cp -- "$f" "$OTHERDIR/old#$f"; done
O formato for variable in GLOB
expandirá a glob para todos os arquivos / diretórios correspondentes (exceto ocultos) e iterar sobre eles, salvando cada um como $variable
(no exemplo acima, $f
). Então, o comando que eu mostro irá iterar todos os arquivos não-ocultos, copiando-os e adicionando o prefixo.
Veja como se faria recursivamente, se necessário,
for f in 'find . -name \*.c'; do name="${f//\.\//__}"; fileName="${name//\//_}" ; echo "Copying $f as $OTHERDIR/old#$fileName"; cp -- "$f" "$OTHERDIR/$fileName"; done
Ainda de outra forma:
for f in $(find dir/ -type f | grep -v 'bk_'); do cp -- "$f" "$(dirname $f)/bk_$(pwgen -s 4 1)_$(basename $f)"; done
Sempre que você executar dessa maneira, ele será dir / from:
dir/foo/foo.c
dir/bar/bar.c
dir/baz/baz.c
Em:
dir/foo/foo.c
dir/foo/bk_R3pP_foo.c
dir/bar/bar.c
dir/bar/bk_o1JD_bar.c
dir/baz/baz.c
dir/baz/bk_0QqF_baz.c
E então:
dir/foo/foo.c
dir/foo/bk_R3pP_foo.c
dir/foo/bk_dV06_foo.c
dir/bar/bar.c
dir/bar/bk_o1JD_bar.c
dir/bar/bk_B68i_bar.c
dir/baz/baz.c
dir/baz/bk_0QqF_baz.c
dir/baz/bk_p6P3_baz.c
E depois ...:
dir/foo/foo.c
dir/foo/bk_R3pP_foo.c
dir/foo/bk_dV06_foo.c
dir/foo/bk_2Ar8_foo.c
dir/bar/bar.c
dir/bar/bk_o1JD_bar.c
dir/bar/bk_B68i_bar.c
dir/bar/bk_wX7Z_bar.c
dir/baz/baz.c
dir/baz/bk_0QqF_baz.c
dir/baz/bk_p6P3_baz.c
dir/baz/bk_fPd3_baz.c
.. e assim por diante.
Aqui está um one-liner usando xargs
, tr
e globbing. Pode ter algum valor.
echo *.c | tr ' ' '\n' | xargs -n1 -I{} cp "{}" "PREFIX{}"
Isso retorna todos os arquivos que correspondem a *.c
como uma string separada por espaço. Em seguida, tr
transforma os espaços extras em novas linhas ( N.B. não testou nomes de arquivos com espaços **). Em seguida, xargs
é preenchido com cada nome de arquivo e executa cp
com o nome e o prefixo apropriados.
*.c
pode ser modificado para outros globs úteis. Outros prefixos na parte xargs
e cp
também podem ser usados.
(requer find
que suporta -print0
)
Semelhante ao acima, podemos usar find
para gerar uma lista de arquivos nulos e alterar xargs
com um sinalizador para separar em nulo
find . -name '*.c' -print0 | xargs -0 -n1 -I{} cp "{}" "PREFIX{}"