せいぜい、私はこのような電話をしたいと思います:
$searchtool /path/to/search/ -contained-file-name "*vacation*jpg"
...このツールが
*vacation*jpg
)検索ツール、tar、unzipなどの使用方法を知っています。これらをシェルスクリプトと組み合わせることができますが、シェルのワンライナーまたは専用ツールである可能性のあるシンプルなソリューションを探しています(GUIツールへのヒントは大歓迎ですが、私のソリューションはコマンドラインベースである必要があります)。
( 圧縮されたアーカイブを再帰的にgrepするにはどうすればよいですか? )から適応
インストール [〜#〜] avfs [〜#〜] 、アーカイブ内の透過的なアクセスを提供するファイルシステム。最初にこのコマンドを1回実行して、マシンのファイルシステムのビューを設定します。このビューでは、ディレクトリのようにアーカイブにアクセスできます。
mountavfs
この後、/path/to/archive.Zip
が認識されたアーカイブである場合、~/.avfs/path/to/archive.Zip#
は、アーカイブのコンテンツを含むように見えるディレクトリです。
find ~/.avfs"$PWD" \( -name '*.7z' -o -name '*.Zip' -o -name '*.tar.gz' -o -name '*.tgz' \) \
-exec sh -c '
find "$0#" -name "*vacation*.jpg"
' {} 'Test::Version' \;
説明:
~/.avfs$PWD
でアーカイブファイルを探します。$0
=アーカイブ名、$1
=検索するパターン)。$0#
は、アーカイブ$0
のディレクトリビューです。find
が{\}
引数の内側の{}
を置き換える場合は、{}
ではなく-exec ;
が必要です(実行するものとしないものがあります)。またはzsh≥4.3の場合:
mountavfs
ls -l ~/.avfs$PWD/**/*.(7z|tgz|tar.gz|Zip)(e\''
reply=($REPLY\#/**/*vacation*.jpg(.N))
'\')
説明:
~/.avfs$PWD/**/*.(7z|tgz|tar.gz|Zip)
は、現在のディレクトリとそのサブディレクトリのAVFSビューのアーカイブと一致します。PATTERN(e\''CODE'\')
は、PATTERNの各一致にCODEを適用します。一致したファイルの名前は$REPLY
にあります。 reply
配列を設定すると、一致が名前のリストに変わります。$REPLY\#
は、アーカイブのディレクトリビューです。$REPLY\#/**/*vacation*.jpg
は、アーカイブ内の*vacation*.jpg
ファイルと一致します。N
glob修飾子は、一致するものがない場合、パターンを空のリストに展開します。AVFSソリューションよりも簡単なものが必要な場合は、Pythonスクリプトを実行して arkfind というスクリプトを作成しました。実際には、
$ arkfind /path/to/search/ -g "*vacation*jpg"
これは再帰的に行われるため、アーカイブ内のアーカイブを任意の深さで見ることができます。
私通常ソリューション:
find -iname '*.Zip' -exec unzip -l {} \; 2>/dev/null | grep '\.Zip\|DESIRED_FILE_TO_SEARCH'
例:
find -iname '*.Zip' -exec unzip -l {} \; 2>/dev/null | grep '\.Zip\|characterize.txt'
Resulsは次のようなものです。
foozip1.Zip:
foozip2.Zip:
foozip3.Zip:
DESIRED_FILE_TO_SEARCH
foozip4.Zip:
...
hitsを含むZipファイルのみが必要な場合:
find -iname '*.Zip' -exec unzip -l {} \; 2>/dev/null | grep '\.Zip\|FILENAME' | grep -B1 'FILENAME'
[〜#〜] filename [〜#〜]ここでは2回使用されているため、変数を使用できます。
FindではPATH/TO/SEARCHを使用できます
IMHOの使いやすさもbashの1つである必要があります:
while read -r Zip_file ; do echo "$Zip_file" ; unzip -l "$Zip_file" | \
grep -i --color=always -R "$to_srch"; \
done < <(find . \( -name '*.7z' -o -name '*.Zip' \)) | \
less -R
とtar(これはテストされていません...)
while read -r tar_file ; do echo "$tar_file" ; tar -tf "$tar_file" | \
grep -i --color=always -R "$to_srch"; \
done < <(find . \( -name '*.tar.gz' -o -name '*.tar' \)) | \
less -R
機能する別のソリューションはzgrep
です
zgrep -r filename *.Zip
libarchive
のbsdtar
は、これらのファイル形式のほとんどを処理できるため、次のことができます。
find . \( -name '*.Zip' -o \
-name '*.tar' -o \
-name '*.tar.gz' -o \
-name '*.tar.bz2' -o \
-name '*.tar.xz' -o \
-name '*.tgz' -o \
-name '*.tbz2' -o \
-name '*.7z' -o \
-name '*.iso' -o \
-name '*.cpio' -o \
-name '*.a' -o \
-name '*.ar' \) \
-type f \
-exec bsdtar tf {} '*vacation*jpg' \; 2> /dev/null
GNU find
を使用して、次のように簡略化できます(大文字と小文字を区別せずに一致するように改善できます)。
find . -regextype egrep \
-iregex '.*\.(Zip|7z|iso|cpio|ar?|tar(|\.[gx]z|\.bz2)|tgz|tbz2)' \
-type f \
-exec bsdtar tf {} '*vacation*jpg' \; 2> /dev/null
ただし、これらの*vacation*jpg
ファイルが見つかったアーカイブのパスは出力されません。その名前を印刷するには、最後の行を次のように置き換えます。
-exec sh -ac '
for ARCHIVE do
bsdtar tf "$ARCHIVE" "*vacation*jpg" |
awk '\''{print ENVIRON["ARCHIVE"] ": " $0}'\''
done' sh {} + 2> /dev/null
次のような出力が得られます。
./a.Zip: foo/blah_vacation.jpg
./a.Zip: bar/blih_vacation.jpg
./a.tar.gz: foo/blah_vacation.jpg
./a.tar.gz: bar/blih_vacation.jpg
またはzsh
を使用:
setopt extendedglob # best in ~/.zshrc
for archive (**/*.(#i)(Zip|7z|iso|cpio|a|ar|tar(|.gz|.xz|.bz2)|tgz|tbz2)(.ND)) {
matches=("${(f@)$(bsdtar tf $archive '*vacation*jpg' 2> /dev/null)"})
(($#matches)) && printf '%s\n' "$archive: "$^matches
}
.jar
または.docx
ファイルのように、Zip
またはtgz
ファイルを装った他のファイル形式がいくつかあることに注意してください。それらをfind
/zsh
検索パターンに追加できます。bsdtar
は拡張子を気にしません(のように、拡張子を決定するために拡張子に依存しませんファイルのタイプ)。
上記の*vacation*.jpg
は、ファイル名だけでなく、完全なアーカイブメンバーパスで照合されるため、vacation.jpg
だけでなくvacation/2014/file.jpg
でも照合されることに注意してください。
ファイル名のみを照合するには、1つのトリックはextractモードを使用することです。-s
(置換)を使用して、正規表現にp
フラグを指定し、一致するファイルを探して、次のようにファイルが抽出されないことを確認します。
bsdtar -'s|.*vacation[^/]*$||' -'s|.*||' -xf "$archive"
Stderrにリストを出力し、すべての行に>>
を追加することに注意してください。いずれの場合でも、bsdtar
は、ほとんどのtar
実装と同様に、改行やバックスラッシュ(\n
または\\
としてレンダリングされる)などの文字が含まれている場合、ファイル名を表示する場合があります。 )。