仅排除tar命令中特定文件夹

3

我想压缩一个目录,它看起来像这样:

dir
└── workspace
└── node_modules
└── subfolder
    └── workspace
    └── node_modules
    └── other_folder

我想要排除所有名为node_modules的文件夹,以及顶层名为workspace的文件夹,但不包括名为workspace的子文件夹。 所以,我最终想要的是这样:

dir
└── subfolder
    └── workspace
    └── other_folder

我正在运行这个命令:tar -czf ./output.tar.gz --exclude=node_modules --exclude=./workspace dir/. 但它会删除所有名为workspace和node_modules的文件夹,因此最终结果如下:
dir
└── subfolder
    └── other_folder

如何只删除我想要的特定工作区文件夹,而不是所有相同名称的文件夹?

2
因此,对于任何更复杂的情况,请使用find创建要压缩的文件列表。然后将此列表传递给tar,最好使用xargs -0或类似方法。 - KamilCuk
实际的文件夹结构比这个复杂得多,包括大量的文件和文件夹。我想要排除而不是包含,因为我只需要排除两个文件夹,并且排除标志在那里并且可以采用模式,就我所知。 - stinaq
2个回答

2

对于所需的情况,可以使用tar排除:

  • --exclude dir/./folder -- 直接应用于dir下的文件夹
  • --exclude folder -- 将在树中的任何位置排除文件夹

应该可以使用:

tar -czf ./output.tar.gz --exclude=node_modules --exclude=dir/./workspace dir/.

当然可以使用--files-from,并使用其他工具生成列表。当列表中的文件数量较大时,通常会优先选择此方法,而不是使用xargs。请注意保留HTML标签。
find dir/. -type f ... | tar cvz ./output.tar.gz -T-

1
"

find 命令有很多选项,可以包含、排除路径、文件、目录等,通常可以按照需要进行筛选。

对于您的情况,我认为应该是:

"
# exclude all folders named node_modules
# exclude the top level folder called workspace
# but no sub folders called workspace
find dir -type f \
    -not -regex '.*/node_modules/.*' -a \
    -not -regex 'dir/workspace/.*' \
    -exec tar -czf ./output.tar.gz {} +

您可能更喜欢使用-exec的替代方法,例如find ... -print0 | xargs -0 tar -czf ./output.tar.gz。我认为最好的方法是find ... -print0 | tar -czf ./output.tar.gz --null -T -,因为如果有太多的文件,即传递给tar的参数太多,它不会失败,我想是这样的。
我用以下命令重新创建了dir目录:
while read l; do
    mkdir -p "$(dirname "$l")"
    touch "$l"
done <<EOF
dir/workspace/1.txt
dir/node_modules/2.txt
dir/subfolder/workspace/3.txt
dir/subfolder/node_modules/4.txt
dir/subfolder/other_folder/5.txt
EOF

然后在repl上测试tar -tf ./output.tar.gz会打印出:
dir/subfolder/workspace/3.txt
dir/subfolder/other_folder/5.txt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接