【问题标题】:How to specify a file prefix in gawk如何在 gawk 中指定文件前缀
【发布时间】:2021-08-06 09:29:50
【问题描述】:

我正在尝试从从软盘映像中提取的文件名列表中识别文件扩展名。该问题与this example 不同,其中文件已从磁盘映像中提取。我是 gawk 的新手,所以它可能不是正确的工具。

ls Sounddsk2.img -a1 > allfilenames

上面的命令创建了如下所示的文件名列表。

flute.pt
flute.ss
flute.vc
guitar.pt
guitar.ss
guitar.vc

下面的gawk 命令识别以.ss 结尾的文件

cat allfilenames | gawk '/[fluteguitar].ss/' > ssfilenames

当只有几个已知文件名时,这会很好。如何以更通用的形式指定文件前缀?

【问题讨论】:

  • 你为什么要使用 ls 创建所有文件名的文件,然后使用 awk 之类的工具来获取以 .ss 结尾的文件,而不是在第一名?

标签: awk text-processing


【解决方案1】:

除非有人能提出更好的建议,否则这似乎是最通用的表达方式。它适用于任何用大写字母、小写字母和数字拼写的前缀文件名

cat allfilenames | gawk '/[a-zA-Z0-9].ss/' > ssfilenames

编辑

αғsнιη 的 first suggested answer 和 jetchisel 的评论提示我尝试使用 gawk 而不使用 cat

gawk '/^([a-zA-Z0-9])\.ss$/' allfilenames > ssfilenames

这也有效

gawk '/[a-zA-Z0-9]\.ss/' allfilenames > ssfilenames

【讨论】:

  • 不用catgawk就可以解析文件就好了。
  • 这里没有 GNU awk 特定的东西,所有的 awk 都可以完成你想要的工作。关于[a-zA-Z0-9]\.ss 同样,我已经解释了它的作用。它会匹配 سلام14Hello.ss 这样的东西,所以你需要开始/结束锚来避免这种情况
  • Afshim,所以 /^ 和 $/ 是开始/结束锚点。正确的 ?括号(和)是必不可少的吗?
  • @αғsнιη,知道了(用 cut'n'paste :)
  • @Greg copy'n'paste :)
【解决方案2】:

请使用find 命令来处理文件名的匹配,您可以尝试使用您显示的示例。您可以在目录本身上运行此命令,而无需将文件名存储到文件中,然后使用awk

find . -regextype egrep -regex '.*/(flute|guitar)\.ss$'

解释: 简单的解释是,使用find 命令的能力在其中添加正则表达式(此处使用egrep 样式);在哪里给正则表达式以匹配文件名fulteguitar 并确保它在此处以 ss 结尾。

【讨论】:

  • Ravinder,egrep 比使用 gawk 有优势吗?
  • @Greg,专家总是建议不要使用 awk 或他们建议使用 find 命令的任何其他语言解析 ls 输出。 egrep 这里只是使用它的正则表达式样式,实际工作是通过 find 命令完成的。如果对您有帮助,请告诉我,谢谢
  • egrep 已弃用,取而代之的是 grep -E
【解决方案3】:

您也可以使用 grep 和 -E 来扩展正则表达式,并使用交替替换来匹配长笛或吉他。

ls Sounddsk2.img -a1 | grep -E "^(flute|guitar)\.ss$" > ssfilenames

模式匹配:

  • ^ 字符串开始
  • (flute|guitar) 长笛或吉他都可以搭配
  • \.ss匹配.ss
  • $ 字符串结束

文件 ssfilenames 包含:

flute.ss
guitar.ss

【讨论】:

  • 第四只鸟,grep比用gawk有优势吗?
【解决方案4】:

使用正则表达式/[fluteguitar].ss/,这匹配其中包含以下字符之一的行fluegit , ar (在括号表达式 [...] 中指定,重复字符只计算一次)后跟单个未转义点 . 匹配的任何单个字符(此处换行符除外),然后是双倍 ss在一行的任何位置。

您需要通过使用线锚的开始^和结束$以及使用匹配组来限制匹配。

awk '/^(flute|guitar)\.ss$/' allFilesName> ssFileNames

只过滤与flute.ss 和/或guitar.ss 匹配的两个文件名。组匹配(...|...) 匹配任何一个由管道分隔的正则表达式,如逻辑或。

如果这些只是前缀并且要匹配以这些字符开头并以.ss 结尾的任何文件,请使用:

awk '/^(flute|guitar).*\.ss$/' allFilesName> ssFileNames

【讨论】:

  • 感谢您澄清开始和结束锚点。所以 '/^[a-zA-Z0-9].*\.ss$/' 会比 '/^(flute|guitar).*\.ss$/' 更通用?因为我只使用长笛和吉他作为前缀名称的例子,但还有很多其他的。
  • @Greg 这取决于你想要匹配的字符,而不是通用的、非通用的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-20
  • 2015-03-16
相关资源
最近更新 更多