好的,所以我在一个文件夹中有一个.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等
提前谢谢你!
答案 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