echo 文件名包含任意顺序的“a”和“b”

echo 文件名包含任意顺序的“a”和“b”

我有一个文件列表如下:

$ echo *
add akfefg aka ab ba

我想以任一顺序回显包含“a”和“b”的文件名。我试过

echo *[ab]*[ba]*
aka ab ba

它还打印“aka”。我试过了

$ echo *a*b* && echo *b*a*
ab
ba

它完成了它的工作,但是'ba'打印在下一行。有没有更简单的方法来做到这一点?谢谢。

答案1

在这个答案中,我正在解决两种不同的场景:

  1. 您想要匹配当前目录中同时包含a和的文件名b然后你想对这些文件做一些事情
  2. 您想要处理两个命令的输出echo以删除换行符。

如果您想循环文件名,那么最好有一个匹配所有名称的模式,然后在循环中使用该模式的扩展。echo不建议使用,因为这会消除各个文件名之间的区别。

zshshell 中,单个模式(*a*b*|*b*a*)将扩展到字母ab以任意顺序出现的所有名称。

bashshell 中,您可以使用单个扩展的通配模式(或ksh类似通配模式)@(*a*b*|*b*a*)来执行相同的操作。默认情况下, shellbash不启用扩展通配模式,因此您需要首先启用它们shopt -s extglob

因此,在bashshell 中,您可以使用类似的东西

shopt -s extglob

for name in @(*a*b*|*b*a*); do
    # process "$name" here
done

生成所需文件名的另一种方法用于加工是通过使用find

find . ! -name . -prune -name '*a*' -name '*b*'

这会(仅)在当前目录中查找同时包含a和的任何名称b。然后,您可以-exec在此命令末尾使用调用一些其他实用程序来执行操作,例如使用

find . ! -name . -prune -name '*a*' -name '*b*' -exec sh -c '
    for name do
        # process "$name" here
    done' sh {} +

此处,find生成内联sh -c脚本使用的文件名。也可以看看了解“find”的 -exec 选项

然而,如果这是一个文本处理练习目的是将两行或多行文本(两次echo调用的输出)排列成一行,然后您可以通过将文本通过管道传输来完成此操作paste -s -。这还将删除文件名中嵌入的任何换行符。以这种方式使用paste而不是tr -d '\n'(这也会删除换行符)可确保生成的文本在末尾由单个换行符终止。

答案2

无需使用方括号,它们可以匹配某个范围内的字符。在第二个示例中,您使用了&&运算符,它用于按顺序执行多个命令。这就是文件逐行打印的原因。

赶紧跑$ echo *a*b* *b*a*

这将在一行中打印所有文件。

编辑冗余匹配,例如cacbca

可以使用扩展通配符,首先在 bash 中启用它$ shopt -s extglob

然后将模式重新定义为:

$ printf '%s ' @(*a*b*|*b*a*)

@(pattern-list) 匹配给定模式之一

相关内容