我正在尝试grep
然后sed
来搜索文件中的特定字符串,这些字符串位于多个tars内,都在一个主tar存档中。现在,我通过
grep
,然后sed
替换文件中的特定字符串。相当乏味。如何使用shell脚本自动执行此操作?
答案 0 :(得分:2)
你可能sed
实际的tar,因为tar本身不会进行压缩。
e.g。
zcat archive.tar.gz|sed -e 's/foo/bar/g'|gzip > archive2.tar.gz
但是,请注意,还会在文件名,用户名和组名中用条形替换foo,仅在 foo 和 bar <时才有效/ em>长度相等
答案 1 :(得分:2)
除了自动执行您概述的步骤之外,没有多少选择,原因是Kimvais在答案中的警告所证明的原因。
tar
命令有一些修改现有tar文件的选项。但是,由于多种原因,它们不适合您的场景,其中之一是需要编辑的嵌套tarball而不是主tarball。所以,你必须做好工作。
主存档中的所有存档是否都被提取到当前目录或命名/创建的子目录中?也就是说,当你运行tar -tf master.tar.gz
时,你会看到:
subdir-1.23/tarball1.tar
subdir-1.23/tarball2.tar
...
或者你看到了:
tarball1.tar
tarball2.tar
(请注意,如果嵌套的tars要嵌入更大的压缩tarball中,它们本身不应该被gzip压缩。)
假设你有子目录符号,那么你可以这样做:
for master in "$@"
do
tmp=$(pwd)/xyz.$$
trap "rm -fr $tmp; exit 1" 0 1 2 3 13 15
cat $master |
(
mkdir $tmp
cd $tmp
tar -xf -
cd * # There is only one directory in the newly created one!
process_tarballs *
cd ..
tar -czf - * # There is only one directory down here
) > new.$master
rm -fr $tmp
trap 0
done
如果您在恶意环境中工作,请使用tmp.$$
以外的其他内容作为目录名称。但是,这种重新打包通常不是在恶意环境中完成的,并且基于进程ID的所选名称足以为所有内容提供唯一的名称。使用tar -f -
进行输入和输出允许您切换目录,但仍然可以在命令行上处理相对路径名。如果你愿意,可能还有其他方法可以解决这个问题。我还使用cat
将输入提供给子shell,以便从上到下的流清晰;从技术上讲,我可以在最后使用) > new.$master < $master
来改进,但是稍后会隐藏一些关键信息。
陷阱命令确保(a)如果脚本被中断(信号HUP,INT,QUIT,PIPE或TERM),则删除临时目录并退出状态为1(不成功)和(b)一次删除子目录,进程可以以零状态退出。
在覆盖之前,您可能需要检查是否存在新的。$ master。您可能需要检查提取操作是否实际提取了内容。您可能需要检查子tarball处理是否确实有效。如果主tarball提取到多个子目录,则需要将“cd *
”行转换为某个循环,该循环遍历它创建的子目录。
如果您对内容有足够的了解并且没有任何问题,可以跳过所有这些问题。
第二个脚本是process_tarballs;它依次处理命令行中的每个tarball,提取文件,进行替换,重新打包结果等。使用两个脚本的一个好处是,你可以分别从处理一个更大的任务来测试tarball处理包含多个tarball的tarball。如果每个子tarball都提取到自己的子目录中,生活将会更容易;如果其中任何一个提取到当前目录中,请确保为其创建一个新的子目录。
for tarball in "$@"
do
# Extract $tarball into sub-directory
tar -xf $tarball
# Locate appropriate sub-directory.
(
cd $subdirectory
find . -type f -print0 | xargs -0 sed -i 's/name/alternative-name/g'
)
mv $tarball old.$tarball
tar -cf $tarball $subdirectory
rm -f old.$tarball
done
你也应该在这里添加陷阱以进行清理,这样脚本可以独立于上面的主脚本运行,但仍然不会留下任何中间目录。在外部脚本的上下文中,您可能不需要在创建新脚本之前保持旧的tarball(所以rm -f $tarbal
而不是移动和删除命令),所以可能不需要这么小心,但是在它自己的权利,脚本应该小心,不要损坏任何东西。