【问题标题】:Create tar gz on linux with specific list of files from sed output使用来自 sed 输出的特定文件列表在 linux 上创建 tar gz
【发布时间】:2017-05-15 04:52:26
【问题描述】:

这是我的命令行:

find . -type f -exec file {} \; \
| sed 's/\(.*png\): .* \([0-9]* x [0-9]*\).*/\2 \1/' \
| sed 's/\(.*jpg\): .* \([0-9]*x[0-9]*\).*/\2 \1/' \
| awk 'int($1) < 1000' \
| sed 's/^.*[[:blank:]]//' \
| tar -czvf images.tar.gz --null -T -

我得到的错误是:

tar: Unix\n./test.png\n./test2.jpg\n: 无法统计: 没有这样的文件或 目录
tar:由于先前的错误而以失败状态退出

我想要的是在当前目录中找到所有宽度小于 1000 像素的图像并将它们压缩到存档中。

【问题讨论】:

  • 为什么在tar 命令中添加--null
  • 错误消息包括\n,它几乎总是“换行”字符。奇怪的是它在那里,你的代码中似乎没有任何东西在创建它。您确定错误消息与代码匹配吗?此外,您可以使用find ... | awk ... | tar ... 来解决问题。您可以在awk 的一个实例中进行多次替换,并打印/测试$2 而不是$1。 (以及稍后的其他非最佳内容)。大概,你一次建立了这个 cmd 1 个附加项?如果没有,请返回再添加 1 个管道并研究之前所做的更改。为什么不find -name '*.jpg' -o -name '*png'
  • @shellter: 因为--nulltar 期望文件名是\0-分隔的。
  • @gniourf_gniourf : 你在回复 melpomene 吗?
  • @shellter:不,给你:)。祝你好运;).

标签: linux bash unix sed tar


【解决方案1】:

要使用--null,您需要先将换行符转换为空值:

...
| tr '\n' '\0' \
| tar -czvf images.tar.gz --null -T -

(已测试,正在运行。)

此外,这里有一些关于速度和风格的建议,按重要性降序排列。

一个。不要在超过您需要的文件上找到并运行file

find . -type f -iname "*.png" -or -iname "*.jpg"

b.对于每个命令可以在多个文件上运行的命令,例如file,使用xargs 可以节省大量时间:

find . -type f -iname "*.png" -or -iname "*.jpg" -print0 | xargs -0 file

c。如果您将| 放在每行的末尾,您可以继续下一行,而无需同时使用\

find . -type f -iname "*.png" -or -iname "*.jpg" -print0 |
  xargs -0 file

d。您可以为自己省去很多麻烦,因为您的最大宽度为 999,只需 greping 对于 1、2 或 3 位宽度,尽管 awk '$1&lt;1000' 最终会更好,以防您想使用不同的阈值:

find . -type f -iname "*.png" -or -iname "*.jpg" -print0 |
  xargs -0 file |
  grep ', [0-9][0-9]\?[0-9]\? x '

e。 grepawksed 快,所以尽可能使用它们:

find . -type f -iname "*.png" -or -iname "*.jpg" -print0 |
  xargs -0 file |
  grep ', [0-9][0-9]\?[0-9]\? x ' |
  grep -o -i '.*\.\(png\|jpg\)'

最终命令:

find . -type f -iname "*.png" -or -iname "*.jpg" -print0 |
  xargs -0 file |
  grep ', [0-9][0-9]\?[0-9]\? x ' |
  grep -o -i '.*\.\(png\|jpg\)' |
  tr '\n' '\0' |
  tar -czvf images.tar.gz --null -T -

【讨论】:

  • 这项工作适用于 size min 1000px。您如何进行相同的研究,但限制变为 2000px2520px
  • F. Hauri 和 Bertrand Martel 的答案都支持任意 width_limit。
【解决方案2】:

您也可以将awk 仅用于:

find . -type f \( -name "*.png" -or -name "*.jpg" \)  -exec file {} \; | awk -v width_limit=1000 '
    {
        match($0, /,\s+([0-9]+)\s*x\s*([0-9]+)/, items)

        if (items[1] < width_limit){
            match($0, /(.*):/, filename)
            print filename[1]
        }             
    }' | tar -czvf allfiles.tar -T -

宽度可以用width_limit变量配置

【讨论】:

    【解决方案3】:

    使用perl的快捷方式:

    find . -type f -exec file {} + |
        perl -ne '
            print $1."\0" if /^(.*):\s*(JPEG|PNG).*,\s*(\d+)\s+x\s*\d+\s*,/ &&
                 $3 < 1000;
            ' | tar -czvf images.tar.gz --null -T -
    

    + 运算符用于findprint0 | xargs -0 的效果相同。

    【讨论】:

    • "使用 + 运算符查找与 print0 | xargs -0 相同的效果。 . .我总是忘记这一点。谢谢你的提醒:)
    猜你喜欢
    • 2022-01-01
    • 2021-12-26
    • 2018-10-29
    • 2015-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多