AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / ubuntu / Perguntas / 1153994
Accepted
WinEunuuchs2Unix
WinEunuuchs2Unix
Asked: 2019-06-26 16:44:37 +0800 CST2019-06-26 16:44:37 +0800 CST 2019-06-26 16:44:37 +0800 CST

Copie o grupo de arquivos (Filename*) para backup (Filename*.bak)

  • 772

Fundo

No Linux você pode:

  • Liste um grupo de arquivos comls Filename*
  • Remova um grupo de arquivos comrm Filename*
  • Mova um grupo de arquivos commv Filename* /New/Directory
  • Mas você não pode copiar um grupo de arquivos com:cp Filename* *.bak

Altere o comando do Linux cppara 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 cpcomando:

$ 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-*
command-line cp ms-dos
  • 8 8 respostas
  • 8060 Views

8 respostas

  • Voted
  1. pa4080
    2019-06-27T04:48:29+08:002019-06-27T04:48:29+08:00

    Aqui está um exemplo de um uso atípico de sed, que é aplicável para esta tarefa:

    sed -i.bak '' file-prefix*
    

    Desta forma, na verdade, sednã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?

    • 16
  2. cbojar
    2019-06-26T19:21:11+08:002019-06-26T19:21:11+08:00

    Você pode usar find:

    find . -max-depth 1 -name 'gmail-meta3*' -exec cp "{}" "{}.bak" \;
    

    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á cpexecutado 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.

    • 15
  3. xiota
    2019-06-26T17:34:10+08:002019-06-26T17:34:10+08:00

    Você pode usar um forloop combash . Normalmente, eu apenas digitaria como uma linha porque essa não é uma tarefa que executo com frequência:

    for f in test* ; do cp -a "$f" "prefix-${f}.ext" ; done
    

    No entanto, se você precisar dele como um script:

    cps() {
       [ $# -lt 2 ] && echo "Usage: cps REGEXP FILES..." && return 1
    
       PATTERN="$1" ; shift
    
       for file in "$@" ; do
          file_dirname=`dirname "$file"`
          file_name=`basename "$file"`
          file_newname=`echo "$file_name" | sed "$PATTERN"`
    
          if [[ -f "$file" ]] && [[ ! -e "${file_dirname}/${file_newname}" ]] ; then
             cp -a "$file" "${file_dirname}/${file_newname}"
          else
             echo "Error: $file -> ${file_dirname}/${file_newname}"
          fi
       done
    }
    

    O uso é semelhante ao rename. Testar:

    pushd /tmp
    mkdir tmp2
    touch tmp2/test{001..100}     # create test files
    ls tmp2
    cps 's@^@prefix-@ ; s@[email protected]@' tmp2/test*    # create backups
    cps 's@[email protected]@' tmp2/test*    # more backups ... will display errors
    ls tmp2
    \rm -r tmp2                   # cleanup
    popd
    
    • 11
  4. steeldriver
    2019-06-26T17:07:25+08:002019-06-26T17:07:25+08:00

    O mais próximo que você provavelmente chegará do paradigma DOS é mcp(do mmvpacote):

    mcp 'gmail-meta3*' 'gmail-meta3#1.bak'
    

    Se zshestiver disponível, seu zmvmódulo contribuído talvez esteja um pouco mais próximo:

    autoload -U zmv
    
    zmv -C '(gmail-meta3*)' '$1.bak'
    

    Eu evitaria lsindependentemente - uma variante de sua própria resposta que é segura para espaços em branco (incluindo novas linhas) seria

    printf '%s\0' gmail-meta3* | while IFS= read -r -d '' f; do cp -a -- "$f" "$f.bak"; done
    

    ou talvez

    printf '%s\0' gmail-meta3* | xargs -0 -I{} cp -a -- {} {}.bak
    
    • 6
  5. Robert Riedl
    2019-06-27T06:03:37+08:002019-06-27T06:03:37+08:00

    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 Filenamearquivos 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'

    • 5
  6. Best Answer
    WinEunuuchs2Unix
    2019-06-26T16:44:37+08:002019-06-26T16:44:37+08:00

    Eu escrevi este one-liner no meu arquivo ~/.bashrc. Respostas muito melhores usando findpodem ser postadas, suponho. Respostas ainda melhores poderiam ser escritas em C. Espero que este Q&A dê o pontapé inicial para melhores respostas:

    cps () {
        # cps "Copy Splat", copy group of files to backup, ie "cps Filename .bak"
        # Copies Filename1 to Filename1.bak, Filename2 to Filename2.bak, etc.
        # If Filename1.bak exists, don't copy it to Filename1.bak.bak
        for f in "$1"*; do [[ ! "$f" == *"$2" ]] && cp -a "$f" "$f$2"; done
    
        # OLD version comments suggested to remove 
        # ls "$1"* | while read varname; do cp -a "$varname" "$varname$2"; done
    }
    
    • for f in "$1"*; do: $1é o gmail-meta3parâmetro e fé 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 que facima. $2é o .bakparâmetro passado. Combinado, isso significa que se o nome do arquivo não terminar em .bak(porque não queremos copiar .bake criar .bak.bak), faça o seguinte
    • cp -a "$f" "$f$2";copie gmail-meta3 para gmail-meta3.bak, etc.
    • done: volta e pega o próximo nome de arquivo na gmail-meta3lista *.

    cps gmail-meta3 .bakSaída de Amostra

    Usando a pergunta como exemplo, veja como ela fica em ação:

    ───────────────────────────────────────────────────────────────────────────────────────────
    rick@alien:~/gmail$ ll gmail-meta3*
    -rw-rw-r-- 1 rick rick 26467821 May 20 16:43 gmail-meta3
    -rw-rw-r-- 1 rick rick 26467821 May 20 16:43 gmail-meta3.bak
    -rw-rw-r-- 1 rick rick      643 May 20 16:43 gmail-meta3-LAB-1558392194-26467821
    -rw-rw-r-- 1 rick rick      643 May 20 16:43 gmail-meta3-LAB-1558392194-26467821.bak
    -rw-rw-r-- 1 rick rick    49607 May 20 16:44 gmail-meta3-REC-1558392194-26467821
    -rw-rw-r-- 1 rick rick    49607 May 20 16:44 gmail-meta3-REC-1558392194-26467821.bak
    -rw-rw-r-- 1 rick rick   728954 Jun 27 17:04 gmail-meta3-YAD-1558392194-26467821
    -rw-rw-r-- 1 rick rick   728954 Jun 27 05:46 gmail-meta3-YAD-1558392194-26467821.bak
    ───────────────────────────────────────────────────────────────────────────────────────────
    rick@alien:~/gmail$ cps gmail-meta3 .bak
    ───────────────────────────────────────────────────────────────────────────────────────────
    rick@alien:~/gmail$ ll gmail-meta3*
    -rw-rw-r-- 1 rick rick 26467821 May 20 16:43 gmail-meta3
    -rw-rw-r-- 1 rick rick 26467821 May 20 16:43 gmail-meta3.bak
    -rw-rw-r-- 1 rick rick      643 May 20 16:43 gmail-meta3-LAB-1558392194-26467821
    -rw-rw-r-- 1 rick rick      643 May 20 16:43 gmail-meta3-LAB-1558392194-26467821.bak
    -rw-rw-r-- 1 rick rick    49607 May 20 16:44 gmail-meta3-REC-1558392194-26467821
    -rw-rw-r-- 1 rick rick    49607 May 20 16:44 gmail-meta3-REC-1558392194-26467821.bak
    -rw-rw-r-- 1 rick rick   728954 Jun 27 17:04 gmail-meta3-YAD-1558392194-26467821
    -rw-rw-r-- 1 rick rick   728954 Jun 27 17:04 gmail-meta3-YAD-1558392194-26467821.bak
    ───────────────────────────────────────────────────────────────────────────────────────────
    rick@alien:~/gmail$ 
    

    Observação: isso usa o -asinalizador com o cpcomando 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 -aparâ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.

    • 4
  7. pLumo
    2019-06-26T22:35:52+08:002019-06-26T22:35:52+08:00

    Este deve fazer conforme solicitado:

    cps(){ p="${@: -1}"; for f in "${@:1:$#-1}"; do cp -ai "$f" "${p//\?/$f}"; done  }
    

    Uso:

    cps FILES... pattern
    Example 1: cps gmail-meta3* ?.bak
    Example 2: cps * save-?
    Example 3: cps * bla-?-blubb
    

    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:

    $ touch 'test};{bla#?"blubb'
    $ cps test* bla-?-blubb
    $ ls
    test};{bla#?"blubb  bla-test};{bla#?"blubb-blubb
    


    Algumas versões anteriores do script para adicionar um sufixo:

    Semelhante à resposta do @WinEunuuchs2Unix, mas acho mais flexível e não analisals :

    cps(){ S="$1"; shift; printf '%s\0' "$@" | xargs -0 -I{} cp -abfS "$S" {} {}; }
    

    Coloque isso em seu .bashrc.

    Uso:

    cps SUFFIX FILES...
    Example: cps .bak gmail-meta3*
    

    Alternativa, com o sufixo como último argumento ( via e via ):

    cps(){ S="${@: -1}"; printf '%s\0' "${@:1:$#-1}" | xargs -0 -I{} cp -abfS "$S" {} {}; }
    

    Uso:

    cps FILES... SUFFIX
    Example: cps gmail-meta3* .bak
    

    • 4
  8. Dan
    2019-06-27T06:44:13+08:002019-06-27T06:44:13+08:00

    Outro método para atingir seu requisito é copiar os arquivos para um diretório temporário e usar o renamecomando para renomeá-los.

    $ mkdir backup
    $ cp filename* /tmp/rename-backup/
    $ rename 's/(filename.*)/$1.bak/' /tmp/rename-backup/*
    $ mv /tmp/rename-backup/* ./
    

    Se você precisar dele como um script, você pode usá-lo assim

    cps () {
        mkdir -p /tmp/rename-backup/
        cp "$1"* /tmp/rename-backup/
        rename "s/($1.*)/\$1.$2/" /tmp/rename-backup/*
        mv "/tmp/rename-backup/$1"*".$2" .
    }
    

    E você pode usar assim:

    cps file bak
    

    Isto é um exemplo

    $ ls -l
    total 0
    -rw-r--r--  1 danny  danny  0 Jun 26 16:23 file a
    -rw-r--r--  1 danny  danny  0 Jun 26 16:23 file ab
    -rw-r--r--  1 danny  danny  0 Jun 26 16:23 file ac
    -rw-r--r--  1 danny  danny  0 Jun 26 16:05 filename1
    -rw-r--r--  1 danny  danny  0 Jun 26 16:05 filename2
    -rw-r--r--  1 danny  danny  0 Jun 26 16:05 filename3
    -rw-r--r--  1 danny  danny  0 Jun 26 16:05 filename4
    $ cps file bak
    $ ls -l
    total 0
    -rw-r--r--  1 danny  danny  0 Jun 26 16:23 file a
    -rw-r--r--  1 danny  danny  0 Jun 26 16:41 file a.bak
    -rw-r--r--  1 danny  danny  0 Jun 26 16:23 file ab
    -rw-r--r--  1 danny  danny  0 Jun 26 16:41 file ab.bak
    -rw-r--r--  1 danny  danny  0 Jun 26 16:23 file ac
    -rw-r--r--  1 danny  danny  0 Jun 26 16:41 file ac.bak
    -rw-r--r--  1 danny  danny  0 Jun 26 16:05 filename1
    -rw-r--r--  1 danny  danny  0 Jun 26 16:41 filename1.bak
    -rw-r--r--  1 danny  danny  0 Jun 26 16:05 filename2
    -rw-r--r--  1 danny  danny  0 Jun 26 16:41 filename2.bak
    -rw-r--r--  1 danny  danny  0 Jun 26 16:05 filename3
    -rw-r--r--  1 danny  wheel  0 Jun 26 16:41 filename3.bak
    -rw-r--r--  1 danny  danny  0 Jun 26 16:05 filename4
    -rw-r--r--  1 danny  danny  0 Jun 26 16:41 filename4.bak
    
    • 2

relate perguntas

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Existe um comando para listar todos os usuários? Também para adicionar, excluir, modificar usuários, no terminal?

    • 9 respostas
  • Marko Smith

    Como excluir um diretório não vazio no Terminal?

    • 4 respostas
  • Marko Smith

    Como descompactar um arquivo zip do Terminal?

    • 9 respostas
  • Marko Smith

    Como instalo um arquivo .deb por meio da linha de comando?

    • 11 respostas
  • Marko Smith

    Como instalo um arquivo .tar.gz (ou .tar.bz2)?

    • 14 respostas
  • Marko Smith

    Como listar todos os pacotes instalados

    • 24 respostas
  • Martin Hope
    Flimm Como posso usar o docker sem sudo? 2014-06-07 00:17:43 +0800 CST
  • Martin Hope
    led-Zepp Como faço para salvar a saída do terminal em um arquivo? 2014-02-15 11:49:07 +0800 CST
  • Martin Hope
    ubuntu-nerd Como descompactar um arquivo zip do Terminal? 2011-12-11 20:37:54 +0800 CST
  • Martin Hope
    TheXed Como instalo um arquivo .deb por meio da linha de comando? 2011-05-07 09:40:28 +0800 CST
  • Martin Hope
    Ivan Como listar todos os pacotes instalados 2010-12-17 18:08:49 +0800 CST
  • Martin Hope
    David Barry Como determino o tamanho total de um diretório (pasta) na linha de comando? 2010-08-06 10:20:23 +0800 CST
  • Martin Hope
    jfoucher "Os seguintes pacotes foram retidos:" Por que e como resolvo isso? 2010-08-01 13:59:22 +0800 CST
  • Martin Hope
    David Ashford Como os PPAs podem ser removidos? 2010-07-30 01:09:42 +0800 CST

Hot tag

10.10 10.04 gnome networking server command-line package-management software-recommendation sound xorg

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve