正则表达式为"第11至第16个字母"

时间:2017-08-23 12:35:25

标签: regex linux bash

我是正则表达的新手。需要帮助来阅读unix系统中的文件。我想在ls命令上应用正则表达式。

我有以下文件:

  

DLERMS0800的 170816 1708209683.csv.gz

     

DLERMS1300的 170816 1330170816.csv.gz

     

DLERMS13001708171330170816.csv.gz

并且想要提取在第11记录到第16位之间具有170816的文件。

我尝试使用下面的命令ls *170816*.gz。但是我得到3个文件名而不是2个。我只想要前两个文件名而不是全部3.你能不能帮忙。

另外我想在这里添加我的第三个文件名已经在末尾包含170816 DLERMS13001708171330 170816。csv.gz。我想在我的ls命令输出中避免这种情况。

7 个答案:

答案 0 :(得分:3)

仅使用bash参数扩展,

for file in *.csv.gz; do  
    [ -e "$file" ] || continue
    [ "${file:10:6}" == "170816" ] && printf "%s\n" "$file"
done
  

${PARAMETER:OFFSET:LENGTH}

     

这个只能扩展参数值的一部分,给定一个开始的位置,也许是一个长度。如果省略LENGTH,则参数将扩展到字符串的末尾。如果LENGTH为负数,则将其作为字符串的第二个偏移量,从字符串的末尾开始计算

根据下面的评论,显然OP希望将目标文件复制到备用路径,在这种情况下,printf()应该用cp替换为必要的参数

[ "${file:10:6}" == "170816" ] && cp -- "$file" path/to/destination

答案 1 :(得分:2)

首先,注意不要将正则表达式与shell glob模式混淆(这就是你想要的)。

你的全球可能是:

ls

匹配10个未知字符,后跟您指定的序列。

根据您的下一步,您可能根本不需要使用for file in ??????????170816*.gz; do something_with "$file" done ,例如,您可以像这样循环遍历这些文件:

echo ??????????170816*.gz
printf '%s\n' ??????????170816*.gz

或使用以下方法之一输出匹配的文件:

nullglob

如果有可能没有文件匹配,那么您可以考虑启用shopt -s nullglob(使用{{1}}),在这种情况下会扩展为空。

答案 2 :(得分:2)

如果您想使用globbing,则与使用正则表达式不同。

在您的示例中,您可以使用“?”作为匹配单个字符的占位符:

因此,要实现您想要的输出,请使用以下模式的ls -

 ls ??????????170816*

答案 3 :(得分:1)

您希望经常使用通配符(不是正则表达式)“任何单个字母”?

ls DLERMS????170816*.csv.gz

对于这个简单的用例,正则表达式更灵活/更强大并且过度使用 但据我所知,ls不支持它们,因此您必须通过其他bash工具来识别文件,以防您需要实际使用正则表达式。

我还反映了我认为你文件名的另一个常见内容,即开头的DLERMS,如果不常见,也可以用?替换这些字母。

答案 4 :(得分:1)

试试这个: ls ??????????170816*

答案 5 :(得分:0)

我认为您不能直接使用ls的正则表达式,但使用egrep时,它可以正常使用。

ls * | egrep "DLERMS[0-9]{4}170816[0-9]{10}.csv.gz"

[0-9] {4} - 任意数字,四次。 [0-9] {10} - 任意数字,十次。

也可以代替" egrep"命令" grep -E",-E选项允许特殊的正则表达式,如" [{|"无需逃避他们" \"。

答案 6 :(得分:0)

使用find和regex的解决方案

find . -regextype egrep -regex "^.{12}170816.*\.gz"

找到读:./xxxxxxxxxxxxx和。{12}表示前十二个,所以170816表示第13记录到第18个