输出 tar 存档中的根目录
我正在尝试使用 shell 脚本自动化您在编译 nginx 之类的东西时所经历的过程。 (我不想使用 apt-get )
目前我有这个:
wget http://nginx.org/download/nginx-1.0.0.tar.gz
tar xf nginx-1.0.0.tar.gz
但接下来我需要找出它提取的目录名称是什么,以便我可以启动配置脚本。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
使用它来查找存档的顶级目录(-ies)。
此处调用 sed 来获取由 tar 打印的路径的第一个组成部分,因此它
会通过执行 s 命令。我使用
@
符号作为分隔符,而不是更常见的/
符号,以避免在正则表达式中转义/
。因此,该命令的意思是:用空字符串替换与/.*
模式(即斜杠后跟任意数量的任意字符)匹配的字符串部分。或者,换句话说,删除第一个斜杠之后(包括)的字符串部分。(必须对其进行修改才能使用绝对文件名;但是,这些在 tar 文件中非常罕见。但请确保这种理论上的可能性不会在您的代码中创建漏洞!)
Use this to find out the top-level directory(-ies) of an archive.
sed
is invoked here to get the first component of a path printed bytar
, so it transformsIt does this by executing s command. I use
@
sign as a delimiter instead of more common/
sign to avoid escaping/
in the regexp. So, this command means: replace part of string that matches/.*
pattern (i.e. slash followed by any number of arbitrary characters) with the empty string. Or, in other words, remove the part of the string after (and including) the first slash.(It has to be modified to work with absolute file names; however, those are pretty rare in tar files. But make sure that this theoretical possibility does not create a vulnerability in your code!)
按照另一个答案中所述使用 sed 是一个很好的方法,但最好在 sed 之前使用
head -1
而不是在之后使用uniq
;这具有更好的性能 - 您只需通过 sed 泵送第一行,这也避免了 uniq 将 sed 的整个输出加载到内存中的要求。此外,如果 tar 包含多个顶级目录,这将返回第一个顶级目录,而uniq
将提供所有顶级目录。我个人认为将 sed 模式匹配中的内部 / 转义为
\/
比引入另一个分隔符(例如 @)更具可读性,但这只是一个偏好问题Using sed as described in the other answer is a good approach, but it's better to use
head -1
before sed instead ofuniq
after; this has much better performance - you are pumping only the first line through sed and this also avoids the requirement of uniq to load the entire output of sed into memory. Furthermore, if the tar contains multiple top level directories, this will return the first top level directory, whereasuniq
will give you all top level directories.I personally find it more readable to escape the internal / in the pattern match of sed as
\/
rather than introducing another delimiter such as @, but that's just a matter of preference这个如何获取所有顶级目录(包括 . ):
要获取第一个顶级目录,我将使用 @thomas-steinbach 发布的解决方案:
How about this one for getting all top level directories (including . ):
To get the first top level directory I would use the solution posted by @thomas-steinbach:
此命令仅使用
tar
:有趣的排除模式(未转义)为
*/*/*
,表示“排除所有两层深度的文件和目录”:第一个*
为基目录,第二个为第一级文件和目录,第三个为第二级文件和目录。仅当通配符仅匹配文件/目录名称(不带斜杠)时,这才有效。这就是
--no-wildcards-match-slash
存在的原因。This command only uses
tar
:The funny exclude pattern, unescaped, is
*/*/*
and means "exclude all files and directories that are two levels deep": the first*
is for the base directory, the second is for the files and directories at first level, the third is for the files and directories at second level.This could only work if the wildcards match just the file/directory names, without the slashes. That's why
--no-wildcards-match-slash
is there.上面的许多答案都是正确的,但我遇到了一种情况,由于管道到head,实际的焦油停止。
Borne shell 中的以下命令:
将生成顶级目录名称:plotutils-3.1
然而,生成的目录要么是空的,要么包含一项。
我用的是ubuntu。要获得 tar 的实际结果,您必须
再次执行另一个命令。我不确定我在这里做错了什么;但这一点应该注意。我在尝试编写 shell 脚本来自动运行 autotool 的配置脚本时发现了这一点。希望这可以帮助其他人。
Many of the above answers are correct, but I encounter a situation where the actual tar stopped as a result of piping to head.
The following command in Borne shell:
Will produce the top directory name: plotutils-3.1
However, the resulting directory will be either empty or containing one item.
I am using ubuntu. To get the actual result of the tar you have to do another command
again. I am not sure I am doing something wrong here; but this should be noted. I found this out when trying to write a shell script to automatically run the autotool's configure script. Hope this may help others.
目录名称应为
nginx-1.0.0
或任何不带.tar.gz
的 tarball 名称。在 wget 和 tar 之后尝试这个:如果您愿意,您也可以使用变量。
但老实说,最好的解决方案是在解压后 cd 到正确的目录,无论您使用 glob 还是变量作为目录名。
The directory name should be
nginx-1.0.0
or whatever the tarball's name is without the.tar.gz
. Try this after wget and tar:You could also use variables, if you like.
Honestly, though, the best solution would be to cd into the proper directory after extracting, whether you use a glob or a variable for the directory name.
这里给出的答案对于绝对路径来说效果不佳,因为它们将它们修剪到路径的第一个目录。如果您使用绝对路径创建了 tar 存档,则以下代码段将返回其原始根目录:
对于压缩 .tar.gz 存档,请添加选项 c。希望这会对其他人有所帮助。
The answers given here doesn't work well for absolute paths as they prune them to the first directory of the path. If you have created a tar archive with absolute paths, the following snippet would return its originally root:
For compresseed .tar.gz archives add the option c. Hope this would help some others.