一起使用egrep和正则表达式

时间:2016-03-16 22:04:04

标签: bash sh

我想在下面的文本文件中搜索以_letter结尾的单词,并将整个部分调到“ :: ”。任何字母之间都没有空格

blahblah:/blahblah::abc_letter:/blahblah/blahblah
blahblah:/blahblah::cd_123_letter:/blahblah/blahblah
blahblah:::/blahblah::24_cde_letter:/blahblah/blahblah
blahblah::/blahblah::45a6_letter:/blahblah/blahblah
blahblah:/blahblah::fgh_letter:/blahblah/blahblah
blahblah:/blahblah::789_letter:/blahblah/blahblah

我试过

egrep -o '*_letter'

egrep -o "*_letter"

但它只返回单词_letter

然后我想将输入提供给shell脚本的参数以进行循环。因此脚本将如下所示

for i in [grep command]

     mkdir $i

end

它将创建以下目录

abc_letter/
cd_123_letter/
24_cde_letter/
45a6_letter/
fgh_letter/
789_letter/

ps:::和_letter之间的结果不包含任何特殊字符,只包含字母数字字符

我的系统也没有perl

2 个答案:

答案 0 :(得分:1)

要从:中提取_letterfile.txt字符串并在for循环中使用它们,您可以使用以下egrep并修改您的:script.sh,就像这样:

#!/bin/bash

for i in $(egrep -o "[^:]+_letter" file.txt); do
    mkdir -p $i
done

然后您运行./script.sh,稍后您使用ls查看,您会看到:

$ ls -1
24_cde_letter
45a6_letter
789_letter
abc_letter
cd_123_letter
fgh_letter
file.txt
script.sh

说明

  • 您的原始egrep -o '*_letter'可能只是将bash文件名扩展与正则表达式混淆,
  • 在bash中,*something使用星形字符串字符来匹配* = anything here + something
  • 但是在正则表达式中,星号*表示前面的字符为零或更多次。由于*位于您所写内容的开头,因此它之前没有任何内容,因此它与那里的任何内容都不匹配。
  • egrep可以匹配的唯一东西是_letter,因为我们使用的是-o选项,它只会在单独的一行显示匹配,因此您最初只看到一行{ {1}}匹配

我们的新变化:

  • _letter模式以egrep开始... [^,一个否定,与您放入的字符相反。我们将]放入。
  • :表示与前一次或多次匹配。
  • 如此组合,它表示寻找任何东西 - 但是 - +,并且这样做一次或多次。
  • 因此当然它匹配:之后的任何内容,并保持匹配,直到模式的下一部分
  • 模式的下一部分只是:
  • _letter因此,只显示匹配的文字,每行一个

通过这种方式,从以下几行:

egrep -o

成功摘录:

blahblah:/blahblah::abc_letter:/blahblah/blahblah

然后,更改您的bash脚本:

  • Bash命令替换abc_letter 以将$()命令的结果发送到for-loop
  • egrep ... for i value...; do语法
  • done只是方便您重新测试,如果目录已经制作,则不会出错。

总而言之,它有助于提取您想要的模式并生成具有这些名称的目录。

答案 1 :(得分:1)

假设没有空格或换行:

for i in $(sed 's/^.*:\([^/]*_letter\):.*$/\1/g' infile); do
    mkdir $i
done