Como copiar e adicionar prefixo aos nomes dos arquivos em um passo?

7

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?

    
por BlackCat 28.07.2015 / 13:19

5 respostas

17

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.

    
por 28.07.2015 / 13:23
6

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.

    
por 28.07.2015 / 13:24
0

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
    
por 03.11.2015 / 18:59
0

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.

    
por 18.04.2017 / 09:02
0

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.

** para aqueles com espaços em seus nomes de arquivo:

(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{}"
    
por 14.11.2018 / 20:34