如何使用 grep GZ 文件来提取 PNG 文件?
How do I grep GZ files to extract PNG files?
好的,所以我在一个文件夹中有一些 .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, etc
并非所有文件都包含 PNG,其中一些包含文件夹结构中的许多文件。我想要的是另一个目标文件夹中的以下内容:
34950560.png, 3959560.png, etc.
提前致谢!
您可以使用文件签名(又名幻数)。 PNG 文件的前几个字节包含一个文件签名,表明该文件是 PNG。如果文件都是 gzip 压缩的,那么 gzip 中会有一个额外的 header,我们可以跳过它。
od 是一个命令,它将以您指定的可读格式转储文件的一部分。我告诉它跳过 gzip header 并以十六进制格式转储。根据我的测试,您将在接下来的八个字节中得到一个字符串“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
假设您的“.GZ”文件实际上是包含多个文件的“.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> '{}'
: 从 stdin 调用 'command' 至多一个参数 (-n1
),将参数放在占位符 {}
.
tar -C "/path/to/extract" -xf '{}' '*.png'
:从 xargs (-xf {}
) 获得的文件中提取,只有以“*.png”结尾的文件。 -C /path/to/extract
: 在那里提取文件。
2>/dev/null
: 忽略从不包含 .png 文件的 GZ 文件引发的错误消息。
此命令将提取指定文件夹中的所有 .png
个文件(保留原始 tar.gz 个文件中的任何目录结构)。跨多个存档的同名 .png
文件将仅存储一次,即最后提取的 .png
文件将覆盖之前的同名文件。
如果你想克服这个问题,那么你需要一个更复杂的脚本,比如:
#!/usr/bin/bash
function extract_png() {
local gzpath=; local extract_path=
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/
等) .
关于 if tar -tf "$gzfile" '*.png' 2>/dev/null; then ...
的解释:如果文件“$gzfile”中有 .png 文件,这将 return 为真。 tar 中的 -t
参数表示 "list contents"。当指定文件 (*.png
) 未包含在存档中时,tar -t
打印一条错误消息(被 2>/dev/null
隐藏)和 returns 一个非零代码来评估这个条件为假。
好的,所以我在一个文件夹中有一些 .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, etc
并非所有文件都包含 PNG,其中一些包含文件夹结构中的许多文件。我想要的是另一个目标文件夹中的以下内容:
34950560.png, 3959560.png, etc.
提前致谢!
您可以使用文件签名(又名幻数)。 PNG 文件的前几个字节包含一个文件签名,表明该文件是 PNG。如果文件都是 gzip 压缩的,那么 gzip 中会有一个额外的 header,我们可以跳过它。
od 是一个命令,它将以您指定的可读格式转储文件的一部分。我告诉它跳过 gzip header 并以十六进制格式转储。根据我的测试,您将在接下来的八个字节中得到一个字符串“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
假设您的“.GZ”文件实际上是包含多个文件的“.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> '{}'
: 从 stdin 调用 'command' 至多一个参数 (-n1
),将参数放在占位符{}
.tar -C "/path/to/extract" -xf '{}' '*.png'
:从 xargs (-xf {}
) 获得的文件中提取,只有以“*.png”结尾的文件。-C /path/to/extract
: 在那里提取文件。2>/dev/null
: 忽略从不包含 .png 文件的 GZ 文件引发的错误消息。
此命令将提取指定文件夹中的所有 .png
个文件(保留原始 tar.gz 个文件中的任何目录结构)。跨多个存档的同名 .png
文件将仅存储一次,即最后提取的 .png
文件将覆盖之前的同名文件。
如果你想克服这个问题,那么你需要一个更复杂的脚本,比如:
#!/usr/bin/bash
function extract_png() {
local gzpath=; local extract_path=
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/
等) .
关于 if tar -tf "$gzfile" '*.png' 2>/dev/null; then ...
的解释:如果文件“$gzfile”中有 .png 文件,这将 return 为真。 tar 中的 -t
参数表示 "list contents"。当指定文件 (*.png
) 未包含在存档中时,tar -t
打印一条错误消息(被 2>/dev/null
隐藏)和 returns 一个非零代码来评估这个条件为假。