我需要在文件中搜索文件tar.gz
而不解压它。之后,我需要将搜索到的文件(如果有)复制到另一个文件夹。
到目前为止我已经有了这个,但是该行的复制部分给了我一个错误。
gunzip -c file.tar.gz | tar tvf - | grep filename | -exec cp {} /folder/another_folder \;
或者是否有更好的方法来搜索文件内的文件tar.gz
而不解压它?
答案1
您的版本tar
不支持切换吗-z
?
$ tar ztvf file.tar.gz | grep fliename
如果存档中存在该文件,则这将返回该文件的名称。
提取文件
如果您想首先搜索该文件,并且仅在存在时才将其提取,则可以执行类似的操作。
$ arc="<tarball>"; file="<file to extract>"; \
tar ztvf $arc | grep $file && tar zxvf $arc $file
示例压缩包
$ tar ztvf ffmpeg.static.64bit.2013-10-05.tar.gz
-rwxr-xr-x root/root 19579304 2013-10-05 00:06 ffmpeg
-rwxr-xr-x root/root 19528712 2013-10-05 00:06 ffprobe
例子
$ arc="ffmpeg.static.64bit.2013-10-05.tar.gz"; file="ffmpeg"; \
tar ztvf $arc | grep $file && tar zxvf $arc $file
-rwxr-xr-x root/root 19579304 2013-10-05 00:06 ffmpeg
ffmpeg
确认
$ ll ffmpeg
-rwxr-xr-x 1 manny manny 19579304 Oct 5 00:06 ffmpeg*
不同的目录
如果您想将提取的文件输出到其他位置,您可以使用tar
的-C
开关。
$ arc="<tarball>"; file="<file to extract>"; \
tar ztvf $arc | grep $file && tar zxvf $arc -C /path/to/dir $file
例子#1
$ arc="ffmpeg.static.64bit.2013-10-05.tar.gz"; \
file="ffmpeg"; tar ztvf $arc | grep $file && tar zxvf $arc -C /tmp $file
确认
$ ll /tmp/ffmpeg
-rwxr-xr-x 1 manny manny 19579304 Oct 5 00:06 /tmp/ffmpeg*
例子#2
$ arc=cp210x.tar.gz; file="cp210x/usb-serial/Makefile"; \
tar ztvf $arc | grep $file && tar zxvf $arc -C /tmp $file
确认
$ ll /tmp/cp210x/usb-serial/Makefile
-rw-rw-r-- 1 manny manny 388 May 13 01:37 /tmp/cp210x/usb-serial/Makefile
例子#3
如果您想提取文件模式,也可以使用通配符。
$ arc=cp210x.tar.gz; file='*Makefile'; \
tar ztvf $arc | grep -E "$file" && tar zxvf $arc -C /tmp --wildcards "$file"
确认
$ find /tmp/cp210x -ls | grep Makefile
26881948 4 -r--r--r-- 1 manny manny 171 Mar 14 2012 /tmp/cp210x/Linux_3.x.x_VCP_Driver_Source/Makefile
26881960 4 -rw-rw-r-- 1 manny manny 388 May 13 01:37 /tmp/cp210x/usb-serial/Makefile
细节
上述内容涉及一些额外的更改。我们正在提取所有匹配的内容'*Makefile'
。请注意,我们现在将其用单引号和双引号括起来。这是为了防止*Makefile
意外扩展。
grep
现在包含 switch -E
,因为我们现在正在搜索正则表达式,而不仅仅是 的输出中的单个字符串tar
。此外, 的参数grep
也不用双引号引起来。
--wildcards
我们现在使用第二个开关tar
,以便我们可以基于模式而不是单个文件进行提取。该参数现在也用双引号括起来以保护它。
答案2
恐怕你无法一步完成这件事。您无法(轻松)将存档的一部分提取到与存档位置不同的位置。你也许可以这样做:
pattern=filename
file_path="$(tar tzf file.tar.gz 2>/dev/null| grep "$pattern")"
if [ ! -n "$file_path ];then
tar xvzf file.tar.gz "$file_path"
cp "$file_path" /new/location
else
echo "No files matching $pattern found in archive"
fi
现在来说说上面的“容易”的话。 GNU 实现tar
有一个--strip-components
选项,可以获取一个数字,并在提取之前从文件名中删除许多组成部分。因此,您可以计算基本名称之前有多少个组件,以便您可以执行某种“在此处提取”操作,然后进行复制:
pattern=filename
file_path="$(tar tzf file.tar.gz | grep "$pattern" )"
file_name="$(basename "$file_path")"
[ -z "$file_path" ] && echo "No files matching $pattern found." && exit 1
components=0
while [ "$file_path" != '/' ];do
file_path=$(dirname "$file_path")
components=$((components+1))
done
tar xvzf file.tar.gz --strip-components "$components" "$file_path" && cp "$file_name" /new/location
答案3
我需要在 tar.gz 文件中搜索文件而不解压它。之后,我需要将搜索到的文件(如果有)复制到另一个文件夹。
到目前为止我已经有了这个,但是该行的复制部分给了我一个错误。
gunzip -c file.tar.gz | tar tvf - | grep filename | -exec cp {} /folder/another_folder \;
或者是否有更好的方法来搜索 tar.gz 文件中的文件而不解压它?
直接搜索 tarball 的 grep 兼容实用程序是乌格勒普有选项-z
:
-z, --decompress
Decompress files to search, when compressed. Archives (.cpio,
.pax, .tar, and .zip) and compressed archives (e.g. .taz, .tgz,
.tpz, .tbz, .tbz2, .tb2, .tz2, .tlz, and .txz) are searched and
matching pathnames of files in archives are output in braces. If
-g, -O, -M, or -t is specified, searches files within archives
whose name matches globs, matches file name extensions, matches
file signature magic bytes, or matches file types, respectively.
Supported compression formats: gzip (.gz), compress (.Z), zip,
bzip2 (requires suffix .bz, .bz2, .bzip2, .tbz, .tbz2, .tb2, .tz2),
lzma and xz (requires suffix .lzma, .tlz, .xz, .txz).
搜索匹配的文件pattern
只需file.tar.gz
一个命令:
ugrep -z -l "pattern" file.tar.gz
要提取与模式匹配的文件,我们可以使用 ugrep 和选项-z
、-l
、--format="%s "
来列出存档中的匹配文件,并将它们提取到folder/another_folder
:
tar xzf file.tar.gz `ugrep -z -l "pattern" --format="%z " file.tar.gz` -C folder/another_folder