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 / 1110359
Accepted
Charles Green
Charles Green
Asked: 2019-01-17 09:59:52 +0800 CST2019-01-17 09:59:52 +0800 CST 2019-01-17 09:59:52 +0800 CST

Mover arquivos de subpastas

  • 772

Eu tenho batido minha cabeça contra isso por um tempo, mas eu realmente não sou um bom roteirista. Desculpas...

Estou executando o Ubuntu/gnome 18.10 e tenho um grande conjunto de imagens exportadas do mac da minha esposa. A estrutura do diretório é:

year1
  (login dir name with spaces) - Month
    Image names
year2
  ...

como em:

2013
  May 4, 2013
    Image1.jpg
    Image2.jpg
  May 5, 2013
    Image 1.jpg
    Image 3.jpg
  June 22, 2013

O que eu gostaria, é:

2013
   January
     All the "january" images...
   February
     All the...

Posso criar os diretórios com bastante facilidade mkdir {January..December}. Mas não consigo descobrir como percorrer a árvore de diretórios feia (exportada do Mac), mover as imagens e excluir o diretório feio.

command-line bash
  • 3 3 respostas
  • 545 Views

3 respostas

  • Voted
  1. Charles Green
    2019-01-19T08:49:25+08:002019-01-19T08:49:25+08:00

    Existe um aplicativo que pode mover e renomear os arquivos em uma única linha de comando -exiftool

    sudo apt install libimage-exiftool-perl
    

    No meu caso, a linha de comando específica usada foi

    exiftool  '-FileName<DateTimeOriginal' -d <path-to-output-dir>/%Y/%m-%B/%Y%m%d_%H%M%S%%-c.%%e . -r
    

    ou

    exiftool  '-FileName<CreateDate' -d <path-to-output-dir>/%Y/%m-%B/%Y%m%d_%H%M%S%%-c.%%e . -r
    

    dependendo de qual tag está presente nas imagens. Se a tag solicitada não estiver presente, o aplicativo emite um aviso e não move esse arquivo, mas continua processando. Este aplicativo também lida com várias imagens com a mesma data/hora, acrescentando um número ao final do nome do arquivo.

    Eu tinha várias imagens sem dados exif e consegui adicionar dados exif às imagens com o comando

    exiftool -createdate='2011:12:04 12:00:00' * -overwrite_original
    

    Como exemplo, coloquei algumas imagens em um diretório ~/aa/test1 e executei a ferramenta, colocando a saída em ~/aa/test2. Os resultados estão abaixo:

    chick@dad:~/aa$ tree .
    .
    ├── test1
    │   ├── DSC00018.JPG
    │   ├── DSC00022.JPG
    │   ├── DSC00024.JPG
    │   ├── DSC00025.JPG
    │   ├── DSC00026.JPG
    │   ├── DSC00028.JPG
    │   ├── DSC00031.JPG
    │   ├── DSC00033.JPG
    │   └── Thumbs.db
    └── test2
        └── 2000
            └── 12-December
                ├── 20001222_185523.JPG
                ├── 20001222_200726.JPG
                ├── 20001222_200819.JPG
                ├── 20001222_201205.JPG
                ├── 20001222_201223.JPG
                ├── 20001222_210536.JPG
                ├── 20001222_211858.JPG
                └── 20001222_215950.JPG
    
    • 2
  2. Best Answer
    pa4080
    2019-01-18T02:54:28+08:002019-01-18T02:54:28+08:00

    Aqui está esse script:

    #!/bin/bash
    
    # The destination where the new directory structure will be created
    DEST="/tmp/new-order-pictures/"
    
    MONTHS=('Jan' 'Feb' 'Mar' 'Apr' 'May' 'Jun' 'Jul' 'Aug' 'Sep' 'Oct' 'Nov' 'Dec')
    
    # Walk through the first level directories, located in the current directory and go inside
    for year in */
    do
        cd "$year"
        # Walk through the months of the year
        for month in "${MONTHS[@]}"
        do
            # Walk through the second level directories
            for dir in */
            do
                # If we have coincidence between the name of the directory and the month
                # go inside, make a new destination directory; ignore character cases^^
                if [[ ${dir^^} =~ ${month^^} ]]
                then
                    cd "$dir"
                    dest="${DEST}${year}${month}"
                    mkdir -p "$dest"
                    find . -type f | while IFS= read -r item
                    do
                        # Copy the files to the new destination and
                        # add the file's md5sum to its name to prevent files lose
                        filename=$(basename -- "$item")
                        extn="${filename##*.}"
                        name="${filename%.*}"
                        cp "$item" "${dest}/${name}-$(md5sum "$item" | cut -f1 -d' ').${extn}"
                    done
                    cd ..
                fi
            done
        done
        cd ..
    done
    

    O script deve ser executado no diretório de primeiro nível onde suas imagens estão localizadas. Você deve ajustar o diretório de destino - DEST="/tmp/new-order-pictures/". Esta versão do script depende de que todos os arquivos estejam em diretórios que contenham o nome de um mês de uma forma ou de outra. Exemplo de uso:

    user@host:~/Pictures$ tree .
    .
    ├── 2013
    │   ├── January 17, 2013
    │   │   ├── Image1.jpg
    │   │   └── Image 3.jpg
    │   ├── January 24, 2013
    │   │   └── Image2.jpg
    │   ├── January 25, 2013
    │   │   └── Image 3.jpg
    │   ├── June 22, 2013
    │   │   └── image1.jpg
    │   ├── May 4, 2013
    │   │   └── Image1.jpg
    │   └── May 5, 2013
    │       ├── Image1.jpg
    │       └── Image 2.jpg
    └── 2014
        ├── January 17, 2014
        │   ├── Image1.jpg
        │   └── Image 3.jpg
        ├── January 24, 2014
        │   └── Image2.jpg
        ├── January 25, 2014
        │   └── Image 3.jpg
        └── May 5
            ├── Image1.jpg
            └── Image 2.jpg
    
    12 directories, 14 files
    
    
    user@host:~/Pictures$ order.sh 
    
    
    user@host:~/Pictures$ tree /tmp/new-order-pictures/
    /tmp/new-order-pictures/
    ├── 2013
    │   ├── Jan
    │   │   ├── Image1-7b71d9fdfe5b15a2d1a4968c195f93ae.jpg
    │   │   ├── Image2-cbf4d36ff84e7ec24c05f8181236e6b8.jpg
    │   │   ├── Image 3-0bca5188fd3f3eb470533fdaf0630633.jpg
    │   │   └── Image 3-6a83880cae1aa57e19a7c45de7759e68.jpg
    │   ├── Jun
    │   │   └── image1-adb3bf995f1a25d008f758a7266d7be5.jpg
    │   └── May
    │       ├── Image1-511d541b35fcb38af8ada18d7961268c.jpg
    │       ├── Image1-a66c5863e6986605cb2ca6d622ae72a0.jpg
    │       └── Image 2-c34ffc32ce5d3901e1ad89b9fd15a877.jpg
    └── 2014
        ├── Jan
        │   ├── Image1-7b71d9fdfe5b15a2d1a4968c195f93ae.jpg
        │   ├── Image2-cbf4d36ff84e7ec24c05f8181236e6b8.jpg
        │   ├── Image 3-0bca5188fd3f3eb470533fdaf0630633.jpg
        │   └── Image 3-6a83880cae1aa57e19a7c45de7759e68.jpg
        └── May
            ├── Image1-511d541b35fcb38af8ada18d7961268c.jpg
            └── Image 2-c34ffc32ce5d3901e1ad89b9fd15a877.jpg
    
    7 directories, 14 files
    

    No meu caso, o script é nomeado order.she está localizado em ~/bin, portanto, posso usá-lo como comando do shell. No exemplo, você pode ver que a estrutura do diretório foi alterada, mas o número de arquivos é 14 em ambas as estruturas.


    Aqui está outra versão do script que usa mvem vez de cpe vai lidar também com os arquivos que não estão em diretórios que contenham o nome de um mês. Antes de executar este script, é uma boa ideia criar uma cópia de backup da estrutura de diretório original.

    #!/bin/bash
    
    # The destination where the new directory structure will be created
    DEST="/tmp/new-order-pictures/"
    
    MONTHS=('Jan' 'Feb' 'Mar' 'Apr' 'May' 'Jun' 'Jul' 'Aug' 'Sep' 'Oct' 'Nov' 'Dec')
    
    # Walk through the first level directories, located in the current directory and go inside
    for year in */
    do
    
        cd "$year"
    
        # Walk through the months of the year
        for month in "${MONTHS[@]}"
        do
            # Walk through the second level directories
            for dir in */
            do
                # If we have coincidence between the name of the directory and the month
                # go inside, make a new destination directory; ignore character cases^^
                if [[ ${dir^^} =~ ${month^^} ]]
                then
    
                    cd "$dir"
                    dest="${DEST}${year}${month}"
                    mkdir -p "$dest"
    
                    while IFS= read -r item
                    do
                        # Copy the files to the new destination and
                        # add the file's md5sum to its name to prevent files lose
                        filename=$(basename -- "$item")
                        extn="${filename##*.}"
                        name="${filename%.*}"
                        mv "$item" "${dest}/${name}-$(md5sum "$item" | cut -f1 -d' ').${extn}"
                    done < <(find . -type f)
    
                    cd ..
    
                fi
    
            done
    
        done
    
        # Dial with the rest of the files for that $year
    
        dest="${DEST}${year}other"
    
        while IFS= read -r item
        do
            mkdir -p "$dest"
            filename=$(basename -- "$item")
            extn="${filename##*.}"
            name="${filename%.*}"
            mv "$item" "${dest}/${name}-$(md5sum "$item" | cut -f1 -d' ').${extn}"
        done < <(find . -type f)
    
        cd ..
    
    done
    

    Exemplo de uso:

    user@host:~/Pictures$ tree .
    .
    ├── 2013
    │   ├── January 17, 2013
    │   │   ├── Image1.jpg
    │   │   ├── Image 3.jpg
    │   │   └── video 7.mpg
    │   ├── January 25, 2013
    │   │   └── Image 3.jpg
    │   ├── June 22, 2013
    │   │   └── image1.jpg
    │   └── May 5, 2013
    │       ├── Image1.jpg
    │       └── Image 2.jpg
    └── 2014
        ├── Apr 7
        │   ├── Image1.jpg
        │   └── Image 2.jpg
        ├── Image 2.jpg
        ├── January 11, 2014
        │   ├── Image1.jpg
        │   └── Image 3.jpg
        ├── some other name
        │   └── some other name file inside.jpg
        ├── some other name file inside.jpg
        └── video 1.avi
    
    9 directories, 15 files
    
    user@host:~/Pictures$ order.sh 
    
    user@host:~/Pictures$ tree /tmp/new-order-pictures/
    /tmp/new-order-pictures/
    ├── 2013
    │   ├── Jan
    │   │   ├── Image1-7b71d9fdfe5b15a2d1a4968c195f93ae.jpg
    │   │   ├── Image 3-0bca5188fd3f3eb470533fdaf0630633.jpg
    │   │   ├── Image 3-6a83880cae1aa57e19a7c45de7759e68.jpg
    │   │   └── video 7-86764d9565469adfb22c8ef4f0b9c04f.mpg
    │   ├── Jun
    │   │   └── image1-adb3bf995f1a25d008f758a7266d7be5.jpg
    │   └── May
    │       ├── Image1-511d541b35fcb38af8ada18d7961268c.jpg
    │       └── Image 2-c34ffc32ce5d3901e1ad89b9fd15a877.jpg
    └── 2014
        ├── Apr
        │   ├── Image1-3c19da25e0e56ef0fc752a9e4f75b190.jpg
        │   └── Image 2-dcc35e86de393a014ac62e8c4390c7e6.jpg
        ├── Jan
        │   ├── Image1-ae34289b0bc5258f286165745ff3c258.jpg
        │   └── Image 3-1724adf2dfcc1d4a0dc50cb38ad2c510.jpg
        └── other
            ├── Image 2-eff5208f7eee6a536e48f9982b918dfb.jpg
            ├── some other name file inside-7d0a68e0b4e9cc3928744cb83f4d1136.jpg
            ├── some other name file inside-c2dd637e94a9025c3e1004d66f59539c.jpg
            └── video 1-c277d93a2427bedf3f0b8ae07427edb9.avi
    
    8 directories, 15 files
    

    Depois disso, você pode entrar no diretório de destino e usar o renamecomando dentro fordo loop para lidar com os nomes longos:

    # For each directory on the second level
    for dir in */*
    do
        cd "$dir"
        rename 's/^.*(\.[0-9a-zA-Z]+)$/our $i; sprintf("Image-%03d$1", 1+$i++)/e' *
        cd ..
        cd ..
    done
    

    Exemplo:

    user@host:~/Pictures$ cd /tmp/new-order-pictures/
    
    user@host:/tmp/new-order-pictures$ for dir in */*; do cd "$dir"; rename 's/^.*(\.[0-9a-zA-Z]+)$/our $i; sprintf("Image-%03d$1", 1+$i++)/e' *; cd ..; cd ..; done
    
    user@host:/tmp/new-order-pictures$ tree .
    .
    ├── 2013
    │   ├── Jan
    │   │   ├── Image-001.jpg
    │   │   ├── Image-002.jpg
    │   │   ├── Image-003.jpg
    │   │   └── Image-004.mpg
    │   ├── Jun
    │   │   └── Image-001.jpg
    │   └── May
    │       ├── Image-001.jpg
    │       └── Image-002.jpg
    └── 2014
        ├── Apr
        │   ├── Image-001.jpg
        │   └── Image-002.jpg
        ├── Jan
        │   ├── Image-001.jpg
        │   └── Image-002.jpg
        └── other
            ├── Image-001.jpg
            ├── Image-002.jpg
            ├── Image-003.jpg
            └── Image-004.avi
    
    8 directories, 15 files
    

    Ou você pode mudar (\.[0-9a-zA-Z]+)com (\.jpg), então na próxima iteração com (\.mpg)(respectivamente Image-com Video-), etc. Referências sobre o uso de rename:

    • Como renomear vários arquivos sequencialmente na linha de comando?

    • Renomear centenas de arquivos de uma só vez para classificação adequada

    • 1
  3. puneet
    2019-01-18T06:41:53+08:002019-01-18T06:41:53+08:00

    Portanto, presumo que você queira uma solução simples e passo a passo. Primeiro, abordaria o problema de espaço em branco e vírgula nas pastas. Eu primeiro colocaria o CD na pasta do ano e usaria renamepara primeiro remover o espaço em branco

    rename "s/ //g" *
    

    Da mesma forma, remova a vírgula

    rename "s/,//g" * 
    

    Agora que tenho todas as pastas desejadas, criaria uma lista mensal usando

    ls | grep "January" > January.txt
    

    Agora crie a pasta "janeiro"

    mkdir January
    

    Em seguida, percorra a lista usando xargspara copiar seu conteúdo

    cat January.txt | xargs -I {} cp -R {}/. ./January/
    
    • 0

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