Fundo
No Linux você pode:
- Liste um grupo de arquivos com
ls Filename*
- Remova um grupo de arquivos com
rm Filename*
- Mova um grupo de arquivos com
mv Filename* /New/Directory
- Mas você não pode copiar um grupo de arquivos com:
cp Filename* *.bak
Altere o comando do Linux cp
para copiar o grupo de arquivos
Eu tenho um grupo de arquivos que gostaria de copiar sem inserir os nomes um por um e usando o cp
comando:
$ ls gmail-meta3*
gmail-meta3 gmail-meta3-REC-1558392194-26467821
gmail-meta3-LAB-1558392194-26467821 gmail-meta3-YAD-1558392194-26467821
Como posso usar algo como o antigo comando DOS copy gmail-meta3* *.bak
?
Não quero digitar um comando semelhante quatro vezes:
cp gmail-meta3-LAB-1558392194-26467821 gmail-meta3-LAB-1558392194-26467821.bak
Estou procurando um script/função/aplicativo que aceite parâmetros para grupos de nomes de arquivos antigos e novos e não algo com nomes de arquivos codificados. Por exemplo, um usuário pode digitar:
copy gmail-meta3* *.bak
ou eles podem digitar:
copy gmail-meta3* save-*
Aqui está um exemplo de um uso atípico de
sed
, que é aplicável para esta tarefa:Desta forma, na verdade,
sed
não alterará os arquivos, pois não fornecemos nenhum comando''
, mas devido à opção-i[suffix]
criará uma cópia de backup de cada arquivo. Eu encontrei essa abordagem quando estava pesquisando Existe alguma maneira de criar uma cópia de backup de um arquivo, sem digitar seu nome duas vezes?Você pode usar
find
:Isso encontrará no diretório atual
.
todos os arquivos com um nome que corresponda ao padrão glob (lembre-se das aspas simples ao redor do padrão para evitar globbing do shell). Para cada arquivo encontrado, ele serácp
executado de nome para nome.bak. O \; no final garante que fará cada arquivo individualmente em vez de passar todos eles de uma vez. A profundidade máxima como 1 apenas pesquisa o diretório atual em vez de recuar para baixo.Você pode usar um
for
loop combash
. Normalmente, eu apenas digitaria como uma linha porque essa não é uma tarefa que executo com frequência:No entanto, se você precisar dele como um script:
O uso é semelhante ao
rename
. Testar:O mais próximo que você provavelmente chegará do paradigma DOS é
mcp
(dommv
pacote):Se
zsh
estiver disponível, seuzmv
módulo contribuído talvez esteja um pouco mais próximo:Eu evitaria
ls
independentemente - uma variante de sua própria resposta que é segura para espaços em branco (incluindo novas linhas) seriaou talvez
solução somente rsync
Se você deseja apenas fazer backup de seus arquivos, pode copiá-los para um novo diretório
rsync /path/to/dir/Filename* /path/to/backupdirectory
Isso copiará os
Filename
arquivos de/path/to/dir/
para/path/to/backupdirectory
.rsync + renomear arquivo
Se você deseja que seus arquivos de backup tenham um sufixo, as coisas ficam complicadas com
rsync
...rsync -Iu /path/to/dir/Filename* /path/to/dir/Filename* -b --backup-dir=/path/to/backupdirectory --suffix=.bak
Isso substituiria os arquivos existentes... com os arquivos existentes (
-I
) mas somente se eles forem (-u
) mais recentes (o que não são) e criar um backup, com um sufixo.Você também pode fazer isso no mesmo diretório. Mas é melhor excluir backups existentes.
rsync -Iu /path/to/dir/Filename* /path/to/dir/Filename* -b --backup-dir=/path/to/backupdirectory --suffix=.bak --exclude '*.bak'
Eu escrevi este one-liner no meu arquivo
~/.bashrc
. Respostas muito melhores usandofind
podem ser postadas, suponho. Respostas ainda melhores poderiam ser escritas em C. Espero que este Q&A dê o pontapé inicial para melhores respostas:for f in "$1"*; do
:$1
é ogmail-meta3
parâmetro ef
é a lista de arquivos correspondentes. Combinado isso significa para gmail-meta3, gmail-meta3-LAB-9999, etc., faça o seguinte[[ ! "$f" == *"$2" ]] &&
:$f
é o mesmo quef
acima.$2
é o.bak
parâmetro passado. Combinado, isso significa que se o nome do arquivo não terminar em.bak
(porque não queremos copiar.bak
e criar.bak.bak
), faça o seguintecp -a "$f" "$f$2";
copie gmail-meta3 para gmail-meta3.bak, etc.done
: volta e pega o próximo nome de arquivo nagmail-meta3
lista *.cps gmail-meta3 .bak
Saída de AmostraUsando a pergunta como exemplo, veja como ela fica em ação:
Observação: isso usa o
-a
sinalizador com ocp
comando para preservar os registros de data e hora e fornecer uma melhor compreensão dos backups de arquivos.Observe como as cópias dos arquivos têm exatamente a mesma data e hora que os originais. Se o
-a
parâmetro fosse omitido, eles receberiam a data e hora atuais e não pareceriam um backup verdadeiro, exceto que o tamanho do arquivo seria o mesmo.Este deve fazer conforme solicitado:
Uso:
Eu escolhi
?
porque#
deve ser citado quando é o primeiro caractere do padrão, caso contrário é reconhecido como o início de um comentário.Teste:
Algumas versões anteriores do script para adicionar um sufixo:
Semelhante à resposta do @WinEunuuchs2Unix, mas acho mais flexível e não analisa
ls
:Coloque isso em seu
.bashrc
.Uso:
Alternativa, com o sufixo como último argumento ( via e via ):
Uso:
Outro método para atingir seu requisito é copiar os arquivos para um diretório temporário e usar o
rename
comando para renomeá-los.Se você precisar dele como um script, você pode usá-lo assim
E você pode usar assim:
Isto é um exemplo