Movendo os arquivos mais recentes de um diretório para outro

4

Estou tentando mover os arquivos mais recentes de um diretório para outro. O comando find localiza os arquivos, mas não os move para outro diretório. O diretório de destino existe.

$ cd /app/path1/path2 && \
    find . -type f -printf "%C@ %p\n" | sort | tail -n 2 | \
    cut -d " " -f 2- |xargs -0 mv -t /app/path1/path2/path3

error:  mv: cannot stat No such file or directory
    
por user67186 11.07.2014 / 23:07

3 respostas

1

Seu problema se deve ao fato de que você assumiu o controle da formatação da saída gerada por find , dividindo agora em novas linhas, \n . Para obter xargs para processar sua saída ao usar -0 , a saída precisa ser separada por caracteres nulos, %code% . Aqui está uma maneira fácil de corrigir isso:

$ find . -type f -printf "%C@ %p\n" | sort | tail -n 2 | \
    cut -d " " -f 2- | tr '\n' '
$ find . -type f -printf "%C@ %p\n" | sort | tail -n 2 | \
    cut -d " " -f 2- | tr '\n' '%pre%' | xargs -0 mv -t /app/path1/path2/path3
' | xargs -0 mv -t /app/path1/path2/path3

A introdução do comando 'tr' \ n '' \ 0 'converte as novas linhas de volta para nulos.

    
por 11.07.2014 / 23:29
1

Evite a opção -0 com xargs ou use -print0. Um trecho da página man do xargs

In these situations it is better to use the -0 option, which prevents such problems. When using this option you will need to ensure that the program which produces the input for xargs also uses a null character as a separator. If that program is GNU find for example, the -print0 option does this for you.

    
por 11.07.2014 / 23:25
0

Se tiver certeza de que os nomes dos arquivos não conterão novas linhas ou caracteres não imprimíveis, esse é um dos raros casos em que faz sentido analisar a saída de ls .

cd /app/path1/path2
latest_file=$(LC_ALL=C ls -cr | head -n 1)
mv "$latest_file" /app/path1/path2/path3

ou se você quiser evitar uma alteração de diretório no processo principal do shell:

latest_file=$(LC_ALL=C ls /app/path1/path2 -cr | head -n 1)
mv "/app/path1/path2/$latest_file" /app/path1/path2/path3

A definição de LC_ALL=C para a execução de ls garante que caracteres não ASCII sejam impressos literalmente em muitos (mas não em todos os sistemas); caracteres de controle (que não são imprimíveis) ainda estão mutilados em muitos sistemas.

Você pode mover vários arquivos de uma só vez. Para ainda lidar com a maioria dos nomes de arquivos, desative o globbing e defina IFS para dividir apenas em novas linhas.

set -f; IFS='
'
mv $(ls -cr /app/path1/path2/* | head -n 2) /app/path1/path2/path3

Se você pode usar o zsh como seu shell, isso é muito mais fácil, já que você pode classificar e selecionar arquivos com um qualificador glob .

mv /app/path1/path2/*(oc[1,2]) /app/path1/path2/path3
    
por 13.07.2014 / 01:49