【问题标题】:awk regular expression to compare the file extensionsawk 正则表达式比较文件扩展名
【发布时间】:2012-10-19 12:49:30
【问题描述】:

我正在尝试查找扩展名为 sh、xls 等的文件,如下面的 FILTER 变量所示。

以下是 ls -ltr 的输出,下面脚本的输出是 hourly_space_update.sh 和 kent.ksh,但我不想要 .ksh 文件,请你告诉我哪里出错了我的正则表达式。

[root@SVRVSVN ~]# ls -ltr
total 20
-rw-r--r--  1 root sqaadmin   44 Oct  9 18:24 hourly_space_update.sh
-rw-r--r--  1 root sqaadmin    0 Oct 30 12:34 kent.ksh
-rw-r--r--  1 root sqaadmin    0 Oct 30 12:34 a.abc
-rw-r--r--  1 root sqaadmin    0 Oct 30 13:02 hh.h
#!/bin/sh

ls -ltr | awk '
BEGIN {
FILTER=".(sh|xls|xlsx|pdf)$"
}
{
for (i = 1; i < 9; i++) $i = ""; sub(/^ */, "");

if(match(tolower($1),FILTER))
{
   print $1
}
}'

【问题讨论】:

  • 记住'.'并不意味着正则表达式中的“点”。它的意思是“任何字符”

标签: regex file awk


【解决方案1】:

尝试使用 (\bsh\b|\bxls\b|\bxlsx\b|\bpdf\b) 过滤器。

在您的过滤器中,您需要 .ksh 文件,因为它包含 sh 序列。

【讨论】:

  • 按照您的建议进行更改后,现在它不会打印任何内容。
  • 无法想象@elrado 对该建议的含义 - \b 是 control-H 字符,没有理由应该出现在您的文件名中,所以现在当然没有任何匹配项。
  • 抱歉:/我使用的是普通的正则表达式语法(\b 表示单词边界)我从未尝试过 awk。我从来没有误导你。
【解决方案2】:

试试这个正则表达式:

\.(sh|xls|xlsx|pdf)$

【讨论】:

  • 我试过得到以下错误:awk: cmd.行:3:警告:转义序列\.' treated as plain .'
  • 再添加一个反斜杠有助于 ---- \\.(sh|xls|xlsx|pdf)$
  • 正确,因为在动态正则表达式中使用字符串时,字符串会被解析两次,一次是在 awk 读取表达式时,一次是在 awk 测试时,因此您需要对任何 RE 元字符进行两次转义您希望将其视为文字。
【解决方案3】:

您的代码实际上可以在我在 cygwin 下运行的 gawk 4.0.1 中运行。

可是你怎么不想做:

awk 'BEGIN {FILTER=".(sh|xls|xlsx|pdf)$"}{if(match(tolower($9),FILTER)){print $9}}'

这会使 for 循环变得多余,并稍微清理一下代码。我猜ls -ltr 的输出每次执行时都使用相同的格式。 :)

不幸的是,我无法使用干净的awk 命令进行测试,但如果这是您awk 的问题,您也可以尝试双重转义\\.。提示是在 if 语句之前 print $1 以确保它包含您期望的内容。

【讨论】:

  • 这是重写 OPs 代码的一种更简洁的方法,但它并不能解决他需要文字“。”的问题。在过滤器中。它对包含空格的文件名也没有帮助。
  • 啊,非常正确!我没有想到的带有空格的文件名。感谢@EdMorton 指出这一点。
  • 不客气。您也不应该指望最终字段编号为 9,因为在某些系统(例如 cygwin)中您也可以在所有者名称中获得空格,因此文件名将位于字段 10 或更多。所以,使用 $NF 更安全。
【解决方案4】:

请参阅我在您迄今为止得到的答案中所做的 cmets,但更重要的是 - 您测试其中一个字段的方法对于包含空格的文件名将失败,并且如果其中一个空格是,任何管道解决方案都将失败换行符。您应该将 shell 用作:

ls -tr *.sh *.xls *.xlsx *.pdf

完全不需要过滤器。

如果你必须保留一个 awk 脚本,那么如果你能保证你的文件名不包含任何空格,那么编写它的方法是这样的:

ls -ltr | awk 'BEGIN{FILTER="\\.(sh|xlsx?|pdf)$"} tolower($NF) ~ FILTER { print $NF }'

请注意,我将您的 RE 缩写为“xslx?”将匹配“xls”或“xlsx”。

在我为您提供包含空格或换行符的文件名的解决方案之前,如果您只想处理文件名,为什么要使用“ls -ltr”而不是简单的“ls -tr”?

【讨论】:

    【解决方案5】:

    在 bash/ksh/zsh 中,可以使用brace expansion:

    ls *.{sh,xls,xlsx,pdf}
    

    还有don't parse ls

    【讨论】:

    • 这个符号也适用于tcsh。哦,还有 +1 提到了那个链接。
    猜你喜欢
    • 2010-09-19
    • 1970-01-01
    • 2013-03-18
    • 1970-01-01
    • 2010-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多