如何从一行文本中提取第二个模式?

时间:2017-10-26 14:58:38

标签: regex ibm-midrange gawk

让我先说一下我的问题,即我在AS / 400上这样做,IBM真的很难保持他们的实用程序是最新的。我想提取像/[a-zA-Z0-9]*.LIB/这样的​​模式,但是找到了第二个匹配。看看下面两条路径的不同之处:

/QSYS.LIB/KDBDFC1_5.LIB/AUTNOTMAIN.PGM
/DATADEV/QSYS.LIB/FPSENGDEV.LIB/AUTNOTMAIN.PGM 

所以,在这种情况下,我想要KDBDFC1_5.LIB和FPSENGDEV.LIB,而不是QSYS.LIB。

我尝试使用带有match()函数的gawk并将我的匹配存储在一个数组中,但似乎我没有第三个参数匹配()“match()不能有3个参数”。我们的gawk版本是3.0.3。是啊。我正在使用perl,试图在命令行设置中完成这项工作。我们的perl版本是5.8.7。如果您的答案包含grep中的一些新的选项,您可能也会认为grep的QSH版本同样老了,尽管有PASE实用程序,如果您知道它们是什么。

我还在敲打这个,但我会很感激任何建议,因为我很快就会头疼。 : - )

5 个答案:

答案 0 :(得分:2)

你可能需要最后一段。以下awk应该有效:

awk -F/ '{print $(NF-1)}' file

KDBDFC1_5.LIB
FPSENGDEV.LIB

或者这个awk可能会通过搜索.LIB并打印第二个字段来实现:

awk -F'.LIB' '{print substr($2,2) FS}' file

KDBDFC1_5.LIB
FPSENGDEV.LIB

答案 1 :(得分:1)

怎么样

perl -lne '@matches = /(\w+\.LIB)/g; print $matches[1] if @matches > 1' file

答案 2 :(得分:1)

如果match不支持数组输出,则可以运行匹配两次,丢弃第一个匹配,然后打印第二个匹配:

$ awk '{p="[a-zA-Z0-9_]*.LIB"; sub(p,""); match($0,p); print substr($0,RSTART,RLENGTH)}' file
KDBDFC1_5.LIB
FPSENGDEV.LIB

答案 3 :(得分:0)

返回second <word>.LIB出现perl -pe 's/^(?:.*?\.LIB).*?([\w_.]*.LIB).*$/\1/g'

last

返回<word>.LIB perl -pe 's/^(?:.*\.LIB).*?([\w_.]*.LIB).*$/\1/g' file 出现^

(?:.*\.LIB)


.*?开头
([\w.]*.LIB)包含.LIB的uncapturing组
<word>.LIB任何事情都是不合适的
.*第一次抓捕小组$
texts任何贪婪的人
fbLoginButton.frame = CGRect(x: 0, y: 0, width: self.tableView.bounds.width, height: YourCellHeight) fbLoginButton.delegate = self myCell.addSubview(fbLoginButton) myCell.selectionStyle = UITableViewCellSelectionStyle.none 完成

答案 4 :(得分:0)

所以......在搜索正则表达式中添加下划线后,以下内容对我有用:

sed 's/.*\/\([[:alnum:]_]*\.LIB\).*/\1/' file

当然,您也可以使用grep -o而不是复杂的正则表达式重写来执行此操作:

grep -o '[[:alnum:]_]*\.LIB' file | awk 'NR%2==0'

这些仅使用与POSIX兼容的功能,因此它们在OS / 400中应该没问题。那就是说,你在awk中寻找这个,所以:

awk '{sub(/.*QSYS\.LIB\//,""); sub(/\/.*/,"")}1' file

如果您知道QSYS.LIB是您尝试避免的事情,可能会在线路早期存在,那么这可能会发生。如果它确实是您想要的两个.LIB文件的第二个,则可能会这样做:

awk '{match($0,/[[:alnum:]_]+\.LIB/); s=substr($0,RSTART+RLENGTH); match(s,/[[:alnum:]_]+\.LIB/); print substr(s,RSTART,RLENGTH)}' file

或者,为便于阅读而分手:

awk '{
  match($0,/[[:alnum:]_]+\.LIB/);
  s=substr($0,RSTART+RLENGTH);
  match(s,/[[:alnum:]_]+\.LIB/);
  print substr(s,RSTART,RLENGTH)
}' file

这仅使用普通旧awk函数match()substr()来(1)从第一个.LIB剥离并将该行的其余部分存储在临时变量中,并且(2)在该变量中找到下一个.LIB

它的优点是不依赖于任何特定的位置 - 即它不会假设“有趣”文件紧接在第一个之后,或者是第二个在线之后,等等。 / p>

尽管如此,这很麻烦,而anubhava的第二个解决方案更加优雅。 : - )