Mova vários arquivos para um diretório se seus nomes contiverem a mesma cadeia de caracteres presente no nome do dir

5

Eu tenho vários arquivos em uma pasta:

ABA.xy
BEB.xy
ACA.xy

Os mesmos arquivos com extensão diferente em outra pasta

ABA.rr
BEB.rr
ACA.rr

Então eu tenho pasta única para cada nome de arquivo

ABA
BEB
ACA

Eu gostaria de fazer o seguinte. se o arquivo com extensão .xy e .rr tiver o mesmo nome da pasta, vá para essa pasta. Por exemplo

ABA.xy and ABA.rr in ABA

Estou familiarizado com mv , mas acho que aqui tenho que escrever um pequeno script para fazer isso.

    
por efrem 30.01.2015 / 12:23

2 respostas

9

Supondo que seus arquivos armazenados em source dir e suas pastas de destino estejam em dest como a seguinte árvore:

$ tree source
source
├── dir1
│   ├── ABA.xy
│   ├── ACA.xy
│   └── BEB.xy
└── dir2
    ├── ABA.rr
    ├── ACA.rr
    └── BEB.rr
2 directories, 6 files

$ tree dest
dest
├── ABA
├── ACA
└── BEB
3 directories, 0 files

O comando seria:

find source -type f -exec sh -c 'noext="${0%.*}"; echo mv '{}' "dest/${noext##*/}/"' {} \;
  • o source é o diretório de origem ou especifica o diretório pai.
  • noext="${0%.*}" retira a extensão dos arquivos e salva o resultado na variável noext .
  • "${noext##*/}" remove a parte do caminho do arquivo da variável noext e seleciona o único nome do arquivo.

  • dest directory é o diretório pai de destino.

  • Portanto, mv '{}' "dest/${noext##*/}/"' move o arquivo atual para o diretório dest/$noext .

    O conteúdo de noext no comando acima é apenas nome do arquivo sem extensão e caminho nele que especifica o diretório de destino que é o mesmo nome do arquivo atual.

Aqui está um exemplo de teste que mostra o resultado do comando

Observe que esses comandos usaram echo para testes e execução a seco. Se você tiver certeza sobre o que é, remova o comando echo na frente de mv para executar a movimentação real.

    
por αғsнιη 30.01.2015 / 13:43
2

Uma abordagem ligeiramente diferente usando rename :

rename 's#.*/(.+)(\.\w+)#mkdir "dest/"; "dest//"#e' source/{a,b}/*

Isso é essencialmente apenas usando uma expressão regular para traduzir os caminhos. Usamos um pouco de Perl (que rename suporta) para criar os novos diretórios e renomear move o arquivo no final.

Não é muito inteligente. Ele não procurará por casos em que não haja um arquivo correspondente (poderíamos pesquisar e remover diretórios com apenas um arquivo) e provavelmente ele explodirá se houver arquivos sem extensões.

$ mkdir -p source/{a,b} dest
$ touch source/a/{ABA,BEB,ACA}.xy
$ touch source/b/{ABA,BEB,ACA}.rr
$ tree
.
├── dest
└── source
    ├── a
    │   ├── ABA.xy
    │   ├── ACA.xy
    │   └── BEB.xy
    └── b
        ├── ABA.rr
        ├── ACA.rr
        └── BEB.rr

$ rename 's#.*/(.+)(\.\w+)#mkdir "dest/"; "dest//"#e' source/{a,b}/*
$ tree
.
├── dest
│   ├── ABA
│   │   ├── ABA.rr
│   │   └── ABA.xy
│   ├── ACA
│   │   ├── ACA.rr
│   │   └── ACA.xy
│   └── BEB
│       ├── BEB.rr
│       └── BEB.xy
└── source
    ├── a
    └── b
    
por Oli 30.01.2015 / 15:08