解凍する方法、tar-xvf - 不正なフォルダに解凍しますか?

解凍する方法、tar-xvf - 不正なフォルダに解凍しますか?

普通は$ mkdir newFolder; $ mv *.zip newFolder; $ cd newFolder; $unzip *.zipアンアーカイブをするのに時々怠惰なせいでランダムなフォルダに入れてする$ unzip *.zipので、他のことを台無しにすることもあります。ここにいくつかのアプローチをリストします。アーカイブされたバージョンのいくつかは間違いなく不都合なロゴを持っていますが、他のものはもう少しシンプルで後者に興味があります。

アーカイブをキャンセルする方法はありますか?別の方法がありますか?

  1. $ find . -anewer fileThatExistedBeforeUnarchieving -ok rm '{}' \;欠点は*.zipディレクトリを一覧表示するため、複数の一致で-okSlow *.zip、Slowを使用する必要があり、何らかの理由で抽出するすべての項目と一致しないようです。

  2. 抽出されたファイルの量が少ない場合、1つずつ抽出する作業は遅くて退屈で、エラーが発生しやすいです。

  3. アーカイブの内容が実際にフォルダであることを確認したいときに、時々、 を使用して確認します。$ unzip -l *.bsdこれは、少なくとも解凍されたobsdバージョンで機能します。

特定のアーカイブツールに言及する場合は、適切な場所に説明してください。しかし、単純にしてください。私は個々のツールではなく、どのように実行するかに興味があります。

答え1

名前で

アーカイブにファイルリストを作成および削除できますが、これは単純なファイル名リストを生成するオプションを持たないunzipや7zなどのアーカイブプログラムでは面倒です。 tarを使用しても、ファイル名に改行文字がないとします。

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

ファイルを削除する代わりに、目的の宛先に移動できます。

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

ヒューズの使用

外部ツールに依存するのではなく(ほとんどの unice で)次のものを使用できます。ヒューズアーカイブを操作するには、通常のファイルシステムコマンドを使用します。

あなたはそれを使用することができますヒューズジッパーzipを表示、解凍しcp、内容を一覧表示するために使用しますfind

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すべてのアーカイブは、アーカイブの内容を保持しているように見える関連ディレクトリ(同じ名前、最後に#を追加)を含むディレクトリ階層全体のビューを作成します。

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

日付別

抽出に加えて、同じ階層に他のアクティビティがないと仮定すると、抽出されたファイルを最新のファイルとして知ることができます。時間。 zipファイルを作成または移動した場合は、それを基準として使用できます。それ以外の場合は、ls -lctr適切な基準時間を決定するために使用されます。ジッパーが削除されないようにしたい場合は、手動で承認する理由はありません。findジッパーを外すことは十分可能です。以下は、zshまたはfind;を使用するコマンド例です。-cminそして-cnewerPrimaryはPOSIXにはありませんが、Linux(およびGNU findを持つ他のシステム)、* BSDおよび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

GNU find、FreeBSD、およびOSXの場合、期限を指定するもう1つの方法は、ファイルを生成し、そのtouchmtimeを使用して期限を設定することです。

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

ファイルを削除する代わりに、目的の宛先に移動できます。これは、GNU / * BSD / OSXルックアップを使用して、必要に応じてターゲットにディレクトリを作成する方法です。

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

Zshと同じです(ほとんど:これはファイルを含むディレクトリだけでなくディレクトリ階層全体をコピーします):

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

警告、この回答ではほとんどのコマンドをテストしていません。削除する前に必ずファイルのリストを確認してください(echo最初に実行してからrm実行)。

答え2

愚かな気がしますが、とにかく似たような問題にぶつかったときに頭を掻き、この台本を書きました。私はファイルのリストを取得するためにcpioフラグを使用します。他のアーカイバにも同じコマンドを使用できます。-itトリッキーな部分は、cpioアーカイブが私がとして抽出したinitrdから取得したものなので、/多くのフォルダとファイルが作業システムと同じ名前を持っているということです。幸いなことに、cpioは私の既存のファイルを上書きしませんでした。私は間違ったコマンドの前に存在していたものを削除しなかったことを確認するために時間チェックを使用します。

#! /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

答え3

アーカイブ内のファイルのリストを提供するにはどうですかxargs rm

それはtar -tf tarbomb.tar | xargs rmまたはになりますunzip --list zipbomb.zip | xargs rm

答え4

zshで次の機能を使用しています。

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

つまり、クリーンアップされた出力のすべてのファイルを削除するコマンドの置き換えですunzip -l

tar tvf同様の方法で使用できます。

関連情報