0

我正在尝试查找扩展名为 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
}
}'
4

5 回答 5

2

试试这个正则表达式:

\.(sh|xls|xlsx|pdf)$
于 2012-10-30T07:57:09.160 回答
1

在 bash/ksh/zsh 中,您可以使用大括号扩展

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

不要解析 ls

于 2012-10-30T14:48:37.280 回答
1

请参阅我在您迄今为止获得的答案中所做的评论,但更重要的是 - 您测试其中一个字段的方法对于包含空格的文件名将失败,并且如果其中一个空格是换行符,任何管道解决方案都将失败。你应该只使用 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”?

于 2012-10-30T12:25:54.783 回答
0

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

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

于 2012-10-30T07:52:50.910 回答
0

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

但是你怎么不想做:

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

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

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

于 2012-10-30T10:40:22.353 回答