首页 > 解决方案 > 如何打印与正则表达式匹配的部分 linux 文件名

问题描述

我想列出 linux 目录中的所有文件,然后对它们应用正则表达式来格式化文件名,并打印这些格式化的文件名。

例子:

ls -lthrh
.
.

-rwxrwxrwx. 1 root   root  633 Oct 31  2016 Oracle_Schedule_ARC-Oracle_ARCH-1477938600005-1002-Oracleorcl-rman1.txt

-rwxrwxrwx. 1 root   root  610 Nov  7  2016 MOD-1478512353102-1002-Oracleorcl-rman1.txt

After applying my regex '.+?(?=-)' I would have everything before the first '-' to be:

Oracle_Schedule_ARC
MOD

我尝试过使用 awk,但我无法将正则表达式传递给它。我稍后申请 | 排序 | uniq 具有正则表达式输出的唯一输出。

标签: regexlinuxstringawk

解决方案


在任何 POSIX shell ( bash, pdksh, ksh93, zsh, dash) 中:

for name in *; do
    printf '%s\n' "${name%%-*}"
done

这将遍历当前目录中的所有名称并输出第一个-字符之前的位。它通过-*使用标准参数替换从文件名中删除最长的后缀字符串匹配来做到这一点。

请注意,这-*是一个 shell globbing 模式,而不是正则表达式。正则表达式对于处理文本很有用,但通配模式通常对于处理文件名和路径名是快速有效的,因为您不必使用正则表达式引擎启动另一个进程,例如awkor sed

bash中,您也可以完全避免使用循环:

set -- *
printf '%s\n' "${@%%-*}"

这首先将位置参数设置为当前目录中的名称。printf然后在一组名称上调用,每个名称都使用与此答案第一部分相同的参数替换进行单独转换。

同样的事情,但使用了位置参数数组以外的数组变量:

names=( * )
printf '%s\n' "${names[@]%%-*}"

推荐阅读