copiando arquivos com nomes específicos para outra pasta

1

Eu tenho uma pasta com muitos arquivos. Quero copiar todos os arquivos que começam com esses nomes (separados por espaço):

abc abd aer ab-x ate

para outra pasta. Como posso fazer isso?

    
por user69453 19.06.2014 / 12:17

3 respostas

3

Com csh , tcsh , ksh93 , bash , fish ou zsh -o cshnullglob , você pode usar expansão de chave e globbing para fazer isso ( -- não é necessário para esses nomes de arquivos, mas eu suponho que eles são apenas exemplos):

cp -- {abc,abd,aer,ab-x,ate}* dest/

Se você preferir não usar a expansão de chaves, você pode usar um loop for (aqui a sintaxe de estilo POSIX / Bourne):

for include in abc abd aer ab-x ate; do
    cp -- "$include"* dest/
done

Se você tiver uma quantidade muito grande de arquivos, isso pode ser lento devido à invocação de cp uma vez por inclusão. Outra maneira de fazer isso seria preencher uma matriz e ir de lá (aqui ksh93 , zsh ou recente bash sintaxe):

files=()
includes=(abc abd aer ab-x ate)

for include in "${includes[@]}"; do
    files+=( "$include"* )
done

cp -- "${files[@]}" dest/        
    
por 19.06.2014 / 12:18
2

Uma nota sobre a expansão de chaves versus globbing.

A expansão de contraventamento não é globbing (embora a distinção não seja tão clara em csh / tcsh onde se originou como em outras shells). É realizado antes globbing.

Então, quando você faz:

cp {a,b}* /dest

Primeiramente, é expandido para:

cp a* b* /dest

Isso significa que o shell terá que expandir dois globs, ou seja, obter a lista completa de arquivos duas vezes e ver qual corresponde ao padrão duas vezes.

Com zsh , isso também significa que se qualquer um do glob não corresponder a nenhum arquivo, o comando todo será cancelado (o que você pode contornar ativando a opção cshnullglob para se comportar como em csh). / p>

Isso também significa que, se você tiver

cp {a,ab}* /dest

cp copia os arquivos ab* duas vezes.

Isso é diferente do:

cp @(a|b)* /dest

de ksh ou bash -O extglob ou zsh -o kshglob ou

cp (a|b)* /dest

de zsh . Lá, é apenas um glob, por isso será mais eficiente, e os arquivos só serão incluídos uma vez.

Com zsh , se você tiver a lista de prefixos em uma matriz:

prefixes=(abc abd aer ab-x ate)
cp -- (${(j:|:)~prefixes})* /dest

(acima, os prefixos são tratados como globs). Isso é juntar os elementos das matrizes com | e considerar o resultado como glob ( ~ ).

Se a lista for grande, o que você pode descobrir é que a execução de cp falha com um erro "arg list too long" . Nesse caso, você pode usar a versão zsh incorporada de cp que você pode carregando o módulo zsh/files ( zmodload zsh/files ).

    
por 19.06.2014 / 14:11
0

Simplesmente você pode fazer

 cp abc* abd* aer* ab-x* ate*  DestinationPath

Uma solução para seu problema estendido pode ser

  1. coloca todos os nomes de arquivos em uma lista, por exemplo list0.txt
  2. Copie tudo com

    cp 'cat list0.txt' DestinationPath # Não precisa de espaço em branco nos nomes dos arquivos

    ou melhor,

    enquanto lê o arquivo -r; do cp "$ file" dest /; feito < list0.txt

Notas:

  • "$ file" porque você pode manipular nome com espaço em branco como One Package.deb
  • -r protege você de sequências de escape.

    -r Backslash does not act as an escape character. The backslash is considered to be part of the line. In particular, a backslash- newline pair may not be used as a line continuation

  •   
por 19.06.2014 / 12:19