Por nome
Você pode gerar a lista de arquivos no arquivo morto e excluí-los, embora isso seja irritantemente complicado com arquivadores como descompactar ou 7z que não têm uma opção para gerar uma lista simples de nomes de arquivos. Mesmo com o tar, isso pressupõe que não há novas linhas nos nomes dos arquivos.
tar tf foo.tar | while read -r file; do rm -- "$file" done
unzip -l foo.zip | awk '
p && /^ --/ {p=2}
p==1 {print substr($0, 29)}
/^ --/ {++p}
' | while …
unzip -l foo.zip | tail -n +4 | head -n -2 | while … # GNU coreutils only
7z l -slt foo.zip | sed -n 's/^Path = //p' | while … # works on tar.*, zip, 7z and more
Em vez de remover os arquivos, você pode movê-los para o destino pretendido.
tar tf foo.tar | while read -r file; do
if [ -d "$file" ]; then continue; fi
mkdir -p "/intended/destination/${file%/*}"
mv -- "$file" "/intended/destination/$file"
done
Usando o FUSE
Em vez de depender de ferramentas externas, você pode (na maioria das unidades) usar o FUSE para manipular arquivos usando comandos comuns do sistema de arquivos.
Você pode usar o Fuse-zip para espiar um zip, extraí-lo com cp
, listar seu conteúdo find
, etc.
mkdir /tmp/foo.d
fuse-zip foo.zip /tmp/foo.d
## Remove the files that were extracted mistakenly (GNU/BSD find)
(cd /tmp/foo.d && find . \! -type d -print0) | xargs -0 rm
## Remove the files that were extracted mistakenly (zsh)
rm /tmp/foo.d/**(:"s~/tmp/foo.d/~~"^/)
## Extract the contents where you really want them
cp -Rp /tmp/foo.d /intended/destination
fusermount -u foo.d
rmdir foo.d
O AVFS cria uma exibição de toda a hierarquia de diretórios, na qual todos os arquivos possuem um diretório associado (mesmo nome com # alinhado no final) que parece conter o conteúdo do arquivo.
mountavfs
## Remove the files that were extracted mistakenly (GNU/BSD find)
(cd ~/.avfs/"$PWD/foo.zip#" && find . \! -type d -print0) | xargs -0 rm
## Remove the files that were extracted mistakenly (zsh)
rm ~/.avfs/$PWD/foo.zip\#/**/*(:"s~$HOME/.avfs/$PWD/foo.zip#~~"^/)
## Extract the contents where you really want them
cp -Rp ~/.avfs/"$PWD/foo.zip#" /intended/destination
umountavfs
Por data
Supondo que não tenha havido outra atividade na mesma hierarquia que sua extração, você pode informar os arquivos extraídos pelo ctime recente . Se você acabou de criar ou mover o arquivo zip, poderá usá-lo como ponto de corte; caso contrário, use ls -lctr
para determinar um tempo de corte adequado. Se você deseja ter certeza de não remover os zíperes, não há motivo para fazer qualquer aprovação manual: find
é perfeitamente capaz de excluí-los. Aqui estão exemplos de comandos usando zsh ou find
; note que as primárias -cmin
e -cnewer
não estão no POSIX, mas existem no Linux (e outros sistemas com localização GNU), * BSD e OSX.
find . \! -name '*.zip' -type f -cmin -5 -exec rm {} + # extracted <5 min ago
rm **/*~*.zip(.cm-6) # zsh, extracted ≤5 min ago
find . -type f -cnewer foo.zip -exec rm {} + # created or moved after foo.zip
Com o GNU find, FreeBSD e OSX, outra maneira de especificar o tempo de corte é criar um arquivo e usá-lo touch
para definir seu mtime para o tempo de corte.
touch -d … cutoff
find . -type f -newercm cutoff -delete
Em vez de remover os arquivos, você pode movê-los para o destino pretendido. Aqui está uma maneira de encontrar o GNU / * BSD / OSX, criando diretórios no destino, conforme necessário.
find . \! -name . -cmin -5 -type f -exec sh -c '
for x; do
mkdir -p "$0/${x%/*}"
mv "$x" "$0/$x"
done
' /intended/destination {} +
Equivalente a Zsh (quase: este reproduz toda a hierarquia de diretórios, não apenas os diretórios que conterão arquivos):
autoload zmv
mkdir -p ./**/*(/cm-3:s"|.|/intended/destination|")
zmv -Q '(**/)(*)(.cm-3)' /intended/destination/'$1$2'
Aviso, não testei a maioria dos comandos nesta resposta. Sempre revise a lista de arquivos antes de remover (execute echo
primeiro e, em seguida, rm
se estiver ok).