如何grep GZ文件以提取PNG文件?

时间:2015-06-15 19:28:11

标签: grep png gz

好的,所以我在一个文件夹中有一个.GZ文件的音调,我希望以递归方式浏览每一个文件并将所有PNG文件提取到另一个目标文件夹中。我该怎么办?

编辑:

我一直在终端上使用此命令在GZ文件中查找字符串,并将整个文件复制到另一个目标目录。然后做它的东西。有一些缺点。一,当我输入" PNG"时,它会找到引用" PNG"等CSS文件的文件。而不是文件类型。其次,除了复制整个文件外,它不会向目录输出任何内容。我想改为提取文件。

find . -type f -print0 | xargs -0 grep -lh "png" | xargs -I % cp % /some_destination

编辑:

这是一个示例文件夹结构:

  

FILE001.GZ,FILE002.GZ,FILE003.GZ等

并非所有PNG都包含PNG,其中一些包含文件夹结构中的许多文件。我想要的是另一个目标文件夹中的以下内容:

  

34950560.png,3959560.png等

提前谢谢你!

2 个答案:

答案 0 :(得分:2)

假设你的" .GZ"文件实际上是gzip压缩" .tar"存档多个文件,然后您可以在一行中完成目标:

find . -type f -iname '*.GZ' | xargs -n1 -I'{}' tar -C "/path/to/extract" -xf '{}' '*.png' 2>/dev/null

说明:

  • find . -type f -iname '*.GZ':查找当前路径中的所有.GZ文件(包括子目录)。 -iname表示不区分大小写,匹配.gz和.GZ文件
  • xargs -n1 -I'{}' <command> '{}':致电&#39;命令&#39;来自stdin的最多一个参数(-n1),将参数放在占位符{}中。
  • tar -C "/path/to/extract" -xf '{}' '*.png':从xargs(-xf {})获取的文件中提取,只有以&#39; *。png&#39;结尾的文件。 -C /path/to/extract:在那里提取文件。
  • 2>/dev/null:将GZ文件中不包含.png文件的错误消息静音。

此命令将提取指定文件夹中的所有.png个文件(保留原始tar.gz文件中的所有目录结构)。跨多个归档的名称相同的.png文件将仅存储一次,即最后提取的.png文件将覆盖先前同名的文件。 如果您想克服这个问题,那么您需要一个更复杂的脚本,如:

#!/usr/bin/bash

function extract_png() {
    local gzpath=$1; local extract_path=$2
    cd "$gzpath" || return 2
    find . -iname '*.GZ' | 
        while read gzfile; do
            if tar -tf "$gzfile" '*.png' 2>/dev/null; then
                local basename=${gzfile%.*}; basename=${basename##*/}
                local extract_to="$extract_path/$basename"
                mkdir -p "${extract_to}"
                tar -C "$extract_to" -xf "$gzfile" '*.png'
            fi
        done
}

extract_png '/path/to/search' '/path/to/save'

extract_png函数会将提取的.png个文件保存到/path/to/save下的每个存档的不同子文件夹中(例如/path/to/save/FILE001//path/to/save/FILE002/等)。< / p>

关于if tar -tf "$gzfile" '*.png' 2>/dev/null; then ...的解释:如果文件中有.png文件,那么这将返回true&#34; $ gzfile&#34;。 tar中的-t参数表示&#34;列出内容&#34;。当归档中未包含指定的文件(*.png)时,tar -t将输出错误消息(由2>/dev/null隐藏)并返回非零代码,该代码将此条件评估为false。

答案 1 :(得分:1)

您可以使用文件签名(又名魔术数字)。 PNG文件的前几个字节包含一个文件签名,表示该文件是PNG。如果这些文件都是gzip,那么gzip会有一个额外的标题,我们可以跳过它。
od是一个命令,它将以您指定的可读格式转储文件的一部分。我告诉它跳过gzip头并以十六进制格式转储。从我的测试中,你将在接下来的8个字节中得到一个字符串“34e6 5580”。如果它与PNG签名匹配,请将其移至新目录并重命名。

COUNTER=0; mkdir PNGDIR
#
for FILE in `ls -1d *`; do  
   od -j 4 -N 10 -x ${FILE} | grep -q "34e6 5580" 
   if [ $? -eq 0 ]; then
     COUNTER=`expr 1 + $COUNTER`
     cp ${FILE} PNGDIR/picture_${COUNTER}.png.gz
   fi
done