【问题标题】:Looping through a pattern for use in a bash find command循环模式以在 bash 查找命令中使用
【发布时间】:2018-06-18 23:53:47
【问题描述】:

我正在尝试编写一个简单的 bash 脚本来查看目录并删除与模式匹配的文件的所有版本(最新版本除外)。这个命令很好用:

find . -type f -name 'a.*.log' -printf '%T@\t%p\n' \
  | sort -t $'\t' -g \
  | head -n -2 \
  | cut -d $'\t' -f 2- \
  | xargs rm -f

这将获取以下文件:a.1.log、a.2.log 和 a.3.log,并删除 a.1.log(假设它是时间戳最旧的)。文件名的版本部分是一个哈希,所以不是按数字顺序排列的(为了简单起见,我更改了它)。

所以,我想做的是遍历一组不同的模式,并将每个模式提供给上面的 find 命令。我已将此示例的脚本简化为如下所示:

#!/bin/bash
FILES="a.*.log
b.*.log
c.*.log"

for f in $FILES
do
    echo "Processing $f"
    find . -type f -name "$f"
done

我运行它的目录有这些文件:

a.1.log, a.2.log, a.3.log, b.1.log, b.2.log, b.3.log, c.1.log, c.2.log , c.3.log

我从上面的脚本得到的输出是:

处理a.1.log ./a.1.log 处理a.2.log ./a.2.log 处理a.3.log ./a.3.log 处理 b.1.log ./b.1.log 处理 b.2.log ./b.2.log 处理 b.3.log ./b.3.log 处理 c.1.log ./c.1.log 处理 c.2.log ./c.2.log 处理 c.3.log ./c.3.log

我需要的是输出看起来像这样:

处理 a.*.log ./a.1.log ./a.2.log ./a.3.log 处理 b.*.log ./b.1.log ./b.2.log ./b.3.log 处理 c.*.log ./c.1.log ./c.2.log ./c.3.log

我尝试过使用数组而不是循环遍历字符串、转义文件模式、在查找中使用单引号和双引号等...但我无法简单地将模式替换为查找.如果我手动单独运行查找,它会给我我正在寻找的输出:

$查找。 -type f -name "a.*.log" ./a.1.log ./a.2.log ./a.3.log $查找。 -type f -name "b.*.log" ./b.1.log ./b.2.log ./b.3.log $查找。 -type f -name "c.*.log" ./c.1.log ./c.2.log ./c.3.log

我找不到任何人循环遍历一组模式并将它们替换为命令的示例。任何帮助都会很棒。

谢谢。

【问题讨论】:

  • 请注意,文件名包含文字换行符是非常合法的;因此,NUL 分隔的流比换行符更安全。
  • 类似地,当xargs 没有通过-0-d 时,它会解析空格——如果你有c. foo bar.log,它会尝试删除文件c.,@ 987654328@,和bar.log
  • 顺便说一句——你回滚我的格式更改是故意的吗?将代码格式化为文本(一行,没有语法高亮或代码格式化)会严重影响其可读性。
  • 顺便说一句,如果你想在没有代码格式的情况下显示数据,四个空格缩进是合适的——只需在块前面加上<!-- language: none --> 以禁用语法突出显示。
  • 抱歉格式化。我已将所有 shell 输出作为代码放入,它是语法突出显示它不应该有的地方。我正在修复它。没想到反应这么快。

标签: regex bash loops find substitution


【解决方案1】:

您遇到的问题是没有引号的变量被拆分但也会发生文件通配现象,这可以使用 shell 选项 noglob set -f 或使用数组并使用双引号来避免:

files=( 'a.*.log' 'b.*.log' 'c.*.log' )

for f in "${files[@]}"; do
...

【讨论】:

  • 使用数组——正如你在这里展示的——比使用set -f好得多。
  • 使用这个导致没有输出。它甚至不为我运行回声。
  • @fudgit,如果你的 shell 真的是 bash(不是 /bin/sh),那不太可能。请参阅ideone.com/L59tSd 以获取在线解释器,该解释器显示了一个循环运行正常运行的相关 glob 表达式。
  • 我很抱歉。我的脚本中有错字。这确实有效。并感谢您的快速响应和对 ideone.com 的引用。这是一个不错的工具。
猜你喜欢
  • 2017-07-08
  • 1970-01-01
  • 1970-01-01
  • 2019-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-05
  • 1970-01-01
相关资源
最近更新 更多