修改嵌套在tar档案中的文件

我正在尝试做一个grep ,然后sed来search文件内的特定string,这些string在多个tar文件中,都在一个主tar文件中。 现在,我通过修改文件

  1. 首先提取主要的tar档案。
  2. 然后提取里面的所有焦油。
  3. 然后做一个recursion的grep ,然后sed来replace文件中的特定string。
  4. 最后再把所有的东西封装到tar档案中,并把所有档案放在主档案里面。

很乏味。 我如何使用shell脚本自动执行此操作?

由于Kimvais回答中的注意事项所表明的原因,除了自动执行您所概述的步骤外,没有太多选择。

tar修改操作

tar命令有一些选项来修改现有的tar文件。 但是,由于多种原因,它们不适合您的场景,其中之一就是需要编辑的嵌套tarball而不是主tarball。 所以,你将不得不做慢速的工作。

假设

主档案库中的所有档案是否被提取到当前目录或已命名/创建的子目录中? 也就是说,当你运行tar -tf master.tar.gz ,你看到:

 subdir-1.23/tarball1.tar subdir-1.23/tarball2.tar ... 

或者你看到:

 tarball1.tar tarball2.tar 

(请注意,如果嵌套的焦点被嵌入到更大的压缩tarball中,它们本身不应该被解压缩。)

master_repackager

假设你有子目录表示法,那么你可以这样做:

 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来将输入提供给子壳体,使得从上到下的流动清晰; 从技术上来说,我可以通过使用) > new.$master < $master来改进,但是后面隐藏了一些关键信息。

陷阱命令确保(a)脚本中断(信号HUP,INT,QUIT,PIPE或TERM),临时目录被删除,退出状态为1(不成功),(b)子目录删除,该过程可以退出零状态。

在覆盖之前,您可能需要检查新的。$ master是否存在。 您可能需要检查提取操作实际提取的东西。 您可能需要检查是否实际上使用了子压缩包处理。 如果主压缩包解压缩到多个子目录中,则需要将“ cd * ”行转换为循环,以循环所创建的子目录。

所有这些问题可以跳过,如果你知道足够的内容,没有出错。

process_tarballs

第二个脚本是process_tarballs; 它依次在其命令行上处理每个tarball,提取文件,进行替换,重新打包结果等。使用两个脚本的一个优点是可以测试tarball处理,与处理包含多个tarballs的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之前保留旧的tarball(所以rm -f $tarbal而不是move和remove命令),但是在它自己的权利脚本应该小心,不要损害任何东西。

概要

  • 你所尝试的并不是微不足道的。
  • 可调试性将作业拆分为两个可独立测试的脚本。
  • 当你知道文件中的真实情况时,处理角落案例要容易得多。

你可能可以sed的实际焦油焦油本身不做压缩本身。

例如

zcat archive.tar.gz|sed -e 's/foo/bar/g'|gzip > archive2.tar.gz

但是,要注意的是,这取代富与酒吧也在文件名,用户名和组名只有当酒吧等长