Como posso mover vários arquivos com nomes diferentes usando mv em um loop?

2

Eu tenho 2500 arquivos com o nome LposK.dat com L variando de 1 a 10 e K variando de 0,00 a 49,80. Eu preciso mover aqueles que têm o mesmo K para uma pasta. Eu consigo fazer isso usando:

find . -name '*posK.dat' -exec mv {} ~/destination/K \;

Mas eu tenho que alterar manualmente o valor de K e repeti-lo várias vezes. Eu queria saber se há alguma maneira de usar o índice de um loop (por exemplo: loop for) dentro dos comandos find e mv para que eu possa escrever um script para fazê-lo.

    
por Elias 30.05.2018 / 21:35

1 resposta

1

Para obter o K de LposK.dat , se essa sequência estiver em $name , poderemos fazer

k=${name%.dat}  # remove ".dat" suffix
k=${k##*pos}    # remove everything up to end of (the last) "pos"

Isso funcionaria mesmo se $name fosse um nome de caminho como some/path/LposK.dat (e mesmo se some/path continha a string pos ), o que é útil quando mais tarde você conectá-lo a find .

Para mover um arquivo:

k=${name%.dat}
k=${k##*pos}

dest="$HOME/destination/$k"
mkdir -p "$dest" && mv "$name" "$dest"  # only move if mkdir did not fail

com find :

find . -type f -name '*pos*.dat' -exec sh -c '
    for name do
        k=${name%.dat}
        k=${k##*pos}

        dest="$HOME/destination/$k"
        mkdir -p "$dest" && mv "$name" "$dest"
    done' sh {} +

Isto daria ao script interno sh -c um número de nomes de caminho como argumentos, e o script iria iterá-los, movendo cada um para o subdiretório correto de $HOME/destination .

Relacionados:

Se os seus arquivos estiverem em um único subdiretório (o diretório atual), você poderá fazer isso ainda mais facilmente sem find :

for name in ./*pos*.dat; do
    [ ! -f "$name" ] && continue  # skip non-regular files

    k=${name%.dat}
    k=${k##*pos}

    dest="$HOME/destination/$k"
    mkdir -p "$dest" && mv "$name" "$dest"
done
    
por 30.05.2018 / 21:45