除了使用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
文件。
答案 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