查找文件是否存在于多个gzip压缩包中的最快方法?

时间:2014-10-28 17:34:31

标签: linux bash tar

除了使用tar tf并根据我正在寻找的文件检查每个文件的输出之外,还有更有效的方法吗?

这就是我现在这样做的方式,但它非常慢(大约有600-1000个档案适合search_patterns):

ARRAY=()
ARRAY[0]=/path/to/archives/*search_pattern1*
ARRAY[1]=/path/to/archives/*search_pattern2*
ARRAY[2]=/path/to/archives/*search_pattern3*

for f in ${ARRAY[@]}
do
    if [[ $f =~ "matching_pattern1" ]]; then
        if tar -tf "$f" | grep "matching_pattern2" ; then
            printf "%s\n" $f;
            exit 0;
        fi
    fi
done

为了它的价值,我的search_patterns连续3天,我想首先找到与matching_pattern1匹配的档案,然后浏览{{1}的所有档案输出包含它的matching_pattern2文件。

3 个答案:

答案 0 :(得分:2)

如果它是一次性操作并且您有常规tar文件(不是gzip),我建议使用strings从tar文件中提取所有ASCII字符串,使用grep检查输出,并且仅解压缩输出与您的模式匹配的文件。文件名以明文形式保存,因此strings可能会向您显示:

$ strings file.tar | grep test
test
test.c
test.c
test.js
test.pl

strings 可能的工作速度比tar tf快。

答案 1 :(得分:2)

没有多个快捷方式,tar文件本质上是顺序的,您可以做的最好是最多处理一次tar文件(可能还有parallel中的多个文件)。使用GNU tar搜索tar文件时,您可以执行以下操作:

tar --wildcards -tzf file.tgz pattern [pattern...]
parallel -tk --tag tar --wildcards -tzvf ::: file*.tgz ::: "pattern" 

使用多个模式,将显示匹配的文件名,如果找到,则退出代码0。记得使用" **"用于匹配跨目录的glob。

然而,如果你只是为每个tar文件寻找一个模式,那么这真的不会比现有的方法快得多。 GNU tar对可搜索的tar文件进行了优化,但压缩会抵消任何好处。 Tar文件可以是增量,拆分,更新甚至包含同一文件的多个副本,除了扫描整个文件之外别无选择(即使大多数tar文件都不那么复杂)。

如果这是一项定期任务,您可以考虑在创建档案时保留索引文件:

tar -czvf file.tgz files [...]  > file.idx 

或者如果您使用GNU tar,请添加:--index-file=file.idx,一个-v仅为文件名,-vv索引文件将包含{{{{1}所示的完整详细信息。 1}}。 (目前似乎没有-tv nul分隔选项。)

(如果有用的话,--index-file0还有替代方案,请参阅https://serverfault.com/questions/59795/is-there-a-smarter-tar-or-cpio-out-there-for-efficiently-retrieving-a-file-store

答案 2 :(得分:1)

你依赖于for循环中的单词分裂。这不是一个好主意(并且对于奇怪命名的文件并不安全)。你最好让globs直接填满阵列。

arr=(/path/to/archives/*search_pattern1* /path/to/archives/*search_pattern2* /path/to/archives/*search_pattern3*)

并使用for f in "${arr[@]}"

然后这样的事情可能会起作用(对于拥有该文件的tarball,如果它是一个静态文件名但是glob总是要扫描整个tarball,它可能会快得多)。

for f in "${arr[@]}"; do
    if tar -tf "$f" "matching_glob" &>/dev/null; do
        echo "File found in $f"
    fi
done