Per nome
Puoi generare l'elenco di file nell'archivio ed eliminarli, anche se questo è fastidiosamente complicato con gli archivi come decomprimere o 7z che non hanno un'opzione per generare un semplice elenco di nomi di file. Anche con tar, questo presuppone che non ci siano nuove righe nei nomi dei file.
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
Invece di rimuovere i file, è possibile spostarli nella destinazione prevista.
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
Utilizzando FUSE
Invece di dipendere da strumenti esterni, è possibile (nella maggior parte dei computer) utilizzare FUSE per manipolare gli archivi utilizzando i normali comandi del filesystem.
Puoi usare Fuse-zip per sbirciare in una zip, estrarla con cp
, elencarne il contenuto con find
, ecc.
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
AVFS crea una vista dell'intera gerarchia di directory in cui tutti gli archivi hanno una directory associata (lo stesso nome con # virata alla fine) che sembra contenere il contenuto dell'archivio.
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
Per data
Supponendo che non vi sia stata alcuna altra attività nella stessa gerarchia della tua estrazione, puoi dire i file estratti dal loro recente ctime . Se hai appena creato o spostato il file zip, puoi usarlo come cutoff; altrimenti utilizzare ls -lctr
per determinare un tempo di interruzione adeguato. Se vuoi assicurarti di non rimuovere le cerniere, non c'è motivo di approvare manualmente: find
è perfettamente in grado di escluderle. Ecco alcuni comandi di esempio che usano zsh o find
; notare che le primarie -cmin
e -cnewer
non sono in POSIX ma esistono su Linux (e altri sistemi con GNU find), * 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
Con GNU find, FreeBSD e OSX, un altro modo per specificare il tempo di cutoff è quello di creare un file e usare touch
per impostare il suo mtime al tempo di cutoff.
touch -d … cutoff
find . -type f -newercm cutoff -delete
Invece di rimuovere i file, è possibile spostarli nella destinazione prevista. Ecco un modo con GNU / * BSD / OSX find, creando directory nella destinazione secondo necessità.
find . \! -name . -cmin -5 -type f -exec sh -c '
for x; do
mkdir -p "$0/${x%/*}"
mv "$x" "$0/$x"
done
' /intended/destination {} +
Zsh equivalente (quasi: questo riproduce l'intera gerarchia di directory, non solo le directory che conterranno i file):
autoload zmv
mkdir -p ./**/*(/cm-3:s"|.|/intended/destination|")
zmv -Q '(**/)(*)(.cm-3)' /intended/destination/'$1$2'
Attenzione, non ho testato la maggior parte dei comandi in questa risposta. Rivedi sempre l'elenco dei file prima di rimuoverlo (esegui echo
prima, quindi rm
se è ok).