Bagaimana cara de-unzip, de-tar -xvf - de-unarchive di folder yang berantakan?

14

Biasanya, saya membatalkan hal $ mkdir newFolder; $ mv *.zip newFolder; $ cd newFolder; $unzip *.ziptetapi terkadang saya malas dan hanya melakukan di folder yang sewenang-wenang $ unzip *.zipsehingga dari waktu ke waktu mengacaukan konten lain. Saya akan mencantumkan di sini beberapa metode - beberapa versi arsip pasti memiliki bendera jelek sementara yang lain lebih sederhana, saya lebih tertarik tentang yang terakhir.

Beberapa cara untuk menghapus pengarsipan, apakah ada yang lain?

  1. $ find . -anewer fileThatExistedBeforeUnarchieving -ok rm '{}' \;Kelemahannya adalah ia mencantumkan *.zipdir, jadi Anda perlu menggunakan lambat -ok, lambat dengan banyak *.zipkecocokan dan, untuk beberapa alasan, sepertinya tidak cocok dengan semua yang diekstraksi.

  2. Jika sejumlah kecil file diekstraksi, satu per satu, lambat, rumit dan rentan kesalahan.

  3. Ketika saya ingin memastikan apakah isi dari arsip tersebut sebenarnya adalah sebuah folder, saya terkadang memeriksanya $ unzip -l *.bsd, berfungsi setidaknya dalam versi unzip yang lama.

Jika Anda merujuk ke alat pengarsipan tertentu, harap sebutkan jika perlu. Tetap sederhana - saya lebih tertarik tentang CARA bagaimana Anda melakukannya, daripada alat tunggal.

Rui F Ribeiro
sumber
1
Lihat juga Lokasi Ekstrak Terkadang - Cara Membersihkan?
Gilles 'SANGAT berhenti menjadi jahat'
Berikut ini skrip yang saya gunakan untuk mengotomatiskan mkdir; unziphal - hal tersebut sehingga saya tidak pernah terlalu malas untuk melakukannya! svn.mikelward.com/svn/scripts/untar
Mikel
2
Lihat pertanyaan dan jawaban terkait ini: unix.stackexchange.com/questions/5123/...
alex

Jawaban:

11

Dengan nama

Anda dapat membuat daftar file dalam arsip dan menghapusnya, meskipun ini mengganggu dengan pengarsipan seperti unzip atau 7z yang tidak memiliki opsi untuk menghasilkan daftar nama file yang sederhana. Bahkan dengan tar, ini mengasumsikan tidak ada baris baru dalam nama 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

Alih-alih menghapus file, Anda bisa memindahkannya ke tujuan yang dituju.

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

Menggunakan FUSE

Alih-alih bergantung pada alat-alat eksternal, Anda dapat (pada sebagian besar unit) menggunakan FUSE untuk memanipulasi arsip menggunakan perintah sistem file biasa.

Anda dapat menggunakan Fuse-zip untuk mengintip ke dalam zip, ekstrak dengan cp, daftar isinya find, dll.

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 membuat tampilan seluruh hierarki direktori Anda di mana semua arsip memiliki direktori terkait (nama yang sama dengan # ditempel di bagian akhir) yang tampaknya menyimpan konten arsip.

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

Tanggal

Dengan asumsi belum ada lain setiap kegiatan dalam hierarki yang sama dari ekstraksi Anda, Anda dapat memberitahu file diekstrak dengan terbaru mereka kriminal . Jika Anda baru saja membuat atau memindahkan file zip, Anda dapat menggunakannya sebagai cutoff; jika tidak gunakan ls -lctruntuk menentukan waktu cutoff yang cocok. Jika Anda ingin memastikan untuk tidak menghapus ritsleting, tidak ada alasan untuk melakukan persetujuan manual: findsangat mampu mengeluarkannya . Berikut adalah contoh perintah menggunakan zsh atau find; perhatikan bahwa primary -cmindan -cnewertidak di POSIX tetapi ada di Linux (dan sistem lain dengan GNU find), * BSD dan 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

Dengan GNU find, FreeBSD dan OSX, cara lain untuk menentukan waktu cutoff adalah dengan membuat file dan menggunakannya touchuntuk mengatur waktu ke waktu cutoff.

touch -d … cutoff
find . -type f -newercm cutoff -delete

Alih-alih menghapus file, Anda bisa memindahkannya ke tujuan yang dituju. Inilah cara menemukan GNU / * BSD / OSX, membuat direktori di tujuan sesuai kebutuhan.

find . \! -name . -cmin -5 -type f -exec sh -c '
    for x; do
      mkdir -p "$0/${x%/*}"
      mv "$x" "$0/$x"
    done
  ' /intended/destination {} +

Setara dengan Zsh (hampir: yang ini mereproduksi seluruh hierarki direktori, bukan hanya direktori yang akan berisi file):

autoload zmv
mkdir -p ./**/*(/cm-3:s"|.|/intended/destination|")
zmv -Q '(**/)(*)(.cm-3)' /intended/destination/'$1$2'

Peringatan, saya belum menguji sebagian besar perintah dalam jawaban ini. Selalu tinjau daftar file sebelum menghapus (jalankan echodulu, lalu rmjika tidak apa-apa).

Gilles 'SANGAT berhenti menjadi jahat'
sumber
Saya akhirnya mengalami masalah ini hari ini. Sebagai root! Pada akhirnya saya menggunakan kombinasi "By name" dan "By date"
phunehehe
1

Aku merasa bodoh, toh aku menggaruk kepalaku untuk menulis naskah ini ketika aku memiliki masalah yang sama. Saya menggunakan cpiodengan -itbendera untuk mendapatkan daftar file; Anda dapat menggunakan perintah yang setara untuk arsip lainnya. Bagian yang sulit adalah, arsip cpio berasal dari initrd dan saya mengekstraksi /, sehingga banyak folder dan file memiliki nama yang sama seperti dalam sistem yang berfungsi. Untungnya cpio tidak menimpa file saya yang ada. Saya menggunakan pemeriksaan waktu untuk memastikan tidak menghapus apa pun yang ada sebelum perintah yang salah.

#! /bin/sh

files=$(cpio -it < /mnt/temp/lglive.cpio)

for i in ${files}
do
    name=$(stat -c "%n" ${i})
    time=$(stat -c "%Y" ${i})
    # Time of the creation of the mess: 1296457595
    if [[ ${time} -gt 1296457590 && ${time} -lt 1296457600 ]]
    then
        if [[ -f ${name} ]]
        # If it is a file, it must have been created as part of the mess.
        then
            echo "rm ${name}"
        elif [[ -d ${name} ]]
        # If it is a directory, it may have been part of the mess
        # or maybe some files underneath it is created as part of the mess.
        then
            if [[ $(ls -A ${name}) ]]
            # If the directory contains something then don't delete it.
            then
                echo "${name} is not empty"
            # If the directory is empty then assume it is rubbish.
            else
                echo "rmdir ${name}"
            fi
        fi
    fi
done

echo "Files and directories still exist after the removal:"
for i in ${files}
do
    if [[ -e ${i} ]]
    then
        echo ${i}
    fi
done
phhehehe
sumber
0

Bagaimana dengan memberi makan daftar file dalam arsip xargs rm?

Itu akan tar -tf tarbomb.tar | xargs rmatau unzip --list zipbomb.zip | xargs rm.

alex
sumber
2
Perintah yang diberikan tidak akan berfungsi dalam kasus umum, dan ini berbahaya karena Anda menghapus file. xargsmengharapkan inputnya dikutip dengan cara aneh yang findtidak menghasilkan. Gunakan xargs -I rm {}agar xargs memproses satu item per baris sebagai gantinya. Untuk perintah unzip, implementasi apa yang Anda miliki? Milik saya (Debian / Ubuntu) tidak --listhanya memiliki -l, dan tidak hanya mencetak nama file, sehingga diperlukan pemrosesan tambahan.
Gilles 'SO- stop being evil'
@Gilles: 1) ya, ini berbahaya, tetapi karena kita mungkin telah menimpa file asli - mereka sudah pergi. 2) Saya tidak membicarakannya find. 3) Anda benar tentang unzip, saya tidak menguji dan tampaknya tidak ada pilihan untuk daftar yang tidak didekorasi. Tidak --listdi Ubuntu saya juga - saya hanya tidak menguji.
alex
Maaf tentang respon kalengan, pengganti tar -tuntuk find. Tapi poin saya yang lain bertahan. Ada risiko nyata bahwa perintah Anda yang diberikan akan menghapus file yang tidak terkait.
Gilles 'SO- stop being evil'
tar -tf tarbomb.tarakan mencetak nama file satu per baris, sehingga Anda bisa melakukan tar -tf tarbomb.tar | while IFS=$'\n' read -r filename; do rm "$filename"; doneatau serupa.
Mikel
0

Tidak benar-benar apa yang Anda minta tetapi bagaimana menggunakan skrip "unzip semua" alih-alih.

unzip *.zip

Dengan begitu output dari setiap file masuk ke direktori itu sendiri.

#!/bin/bash
for f in *.zip ; do unzip -n "$f" -d "${f/%zip/out}"; done
Johan
sumber
0

Saya menggunakan fungsi berikut di zsh:

ununzip () {
    rm -r $(unzip -l $1 | grep -v 'Archive:' | \
    grep '[/.]' | sed 's![^a-zA-Z]([a-zA-Z./])!\1!')
}

Yaitu perintah substitusi untuk menghapus semua file dalam output dibersihkan dari unzip -l.

tar tvf dapat digunakan dengan cara yang sama.

Edd Steel
sumber