通过文件名中字符的位置搜索 Unix 文件名

通过文件名中字符的位置搜索 Unix 文件名

我有2个文件。

  1. 文件 1 = ABC2019120601C
  2. 文件 2 = ABC2019120611C

如果我输入 ls -l ABC*C 它将输出所有 2 个文件。有没有办法通过字符的确切位置来查找文件?

例如

  • 第一位置 = A
  • 第二个位置 = B
  • 第三位置 = C
  • 第 14 位 = C

然后它只会输出文件 ABC2019120601C 如果可能的话请帮忙

答案1

您可以使用?来匹配任何单个字符(而不是*匹配零个或多个字符)。例如

ls -ld ABC??????????C

但请注意两个都您的示例文件名符合您的条件(它们仅在第 12 个字符上有所不同)。

答案2

使用zsh,您可以执行以下操作:

set -o extendedglob # best in ~/.zshrc
ls -ld ABC?(#c10)C*

where(#cx,y)类似于正则表达式{x,y},指定前一个原子的重复间隔(此处?匹配任何单个字符)。

ksh93 中的等效项是:

ls -ld ABC{10}(?)C*

bash/sh没有等效项,但假设$IFS不包含?字符,您应该能够这样做:

repeat() {
  awk -- '
    BEGIN {
      for (i = 0; i < ARGV[1]; i++) printf "%s", ARGV[2]
      if (ARGV[1]) printf "\n"
    }' "$@"
}

ls -ld ABC$(repeat 10 '?')C

要按位置搜索,使用 ksh93,您可以使用其前瞻运算符:

ls -ld ~(P:(?=.{0}(A))(?=.{1}(B))(?=.{2}(C))(?=.{13}(C))*

其中偏移量为:0、1、2、13

  • ~(P:...):ksh93 glob 可以使用多种不同的语法。这里使用类似 perl 的正则表达式。
  • (?=...)是像 Perl 中那样的正向预测断言,如果内部匹配,则以 0 宽度进行现场匹配。
  • .{13}(C): 匹配 C 后跟 13 个字符。由于所有(?=...)匹配的宽度都为零,因此它们最终都在主题的开头匹配)。我们使用.{13}(C)而不是.{13}C解决 ksh93 中的错误。

使用zsh,您可以通过在 glob 限定符中进行 PCRE 匹配来执行相同的操作:

set -o rematchpcre
ls -ld *(e['[[ $REPLY =~ "^(?=.{0}A)(?=.{1}B)(?=.{2}C)(?=.{13}C)" ]]'])

或者做

ls -ld *(e['[[ $REPLY[1,3]$REPLY[14] = ABCC ]]'])

或者使用辅助函数,例如:

offsets() {
  local c o
  for o c {
    [[ $REPLY[o] = $c ]] || return
  }
}
ls -ld *(e['offsets 1 A 2 B 3 C 14 C'])

相关内容