如何从一行文本中提取第二个模式?
How to extract the second pattern from a line of text?
让我以我在 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。
我尝试将 gawk 与 match() 函数一起使用,并将我的匹配项存储在一个数组中,但似乎我不能使用 match() "match() cannot have 3 arguments" 的第三个参数。我们的 gawk 版本是 3.0.3。是的。我在玩 perl,试图让它在命令行设置中工作。我们的 perl 版本是 5.8.7。如果您的答案包括 grep 中的一些奇特的新选项,您也可以认为 grep 的 QSH 版本同样古老,尽管有 PASE 实用程序,如果您知道它们是什么的话。
我还在努力解决这个问题,但我很可能很快就会头疼,因此请提供任何建议。 :-)
您可能需要 last-1 片段。以下 awk
应该有效:
awk -F/ '{print $(NF-1)}' file
KDBDFC1_5.LIB
FPSENGDEV.LIB
或者这个 awk
可能会通过搜索 .LIB
并打印第二个字段来工作:
awk -F'.LIB' '{print substr(,2) FS}' file
KDBDFC1_5.LIB
FPSENGDEV.LIB
怎么样
perl -lne '@matches = /(\w+\.LIB)/g; print $matches[1] if @matches > 1' file
return second
出现 <word>.LIB
:
perl -pe 's/^(?:.*?\.LIB).*?([\w_.]*.LIB).*$//g'
return <word>.LIB
的 last
出现 :
perl -pe 's/^(?:.*\.LIB).*?([\w_.]*.LIB).*$//g' file
^
开始于
(?:.*\.LIB)
正在取消捕获包含 .LIB 的组
.*?
有什么不满意的地方
([\w.]*.LIB)
第一个捕获组 <word>.LIB
.*
什么都贪心
$
完成
如果match
不支持数组输出,你可以运行匹配两次,丢弃第一个匹配,打印第二个:
$ awk '{p="[a-zA-Z0-9_]*.LIB"; sub(p,""); match([=10=],p); print substr([=10=],RSTART,RLENGTH)}' file
KDBDFC1_5.LIB
FPSENGDEV.LIB
所以...在搜索正则表达式中添加下划线后,以下对我有用:
sed 's/.*\/\([[:alnum:]_]*\.LIB\).*//' 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
文件中的 second,这可能会:
awk '{match([=13=],/[[:alnum:]_]+\.LIB/); s=substr([=13=],RSTART+RLENGTH); match(s,/[[:alnum:]_]+\.LIB/); print substr(s,RSTART,RLENGTH)}' file
或者,为了便于阅读,拆分为:
awk '{
match([=14=],/[[:alnum:]_]+\.LIB/);
s=substr([=14=],RSTART+RLENGTH);
match(s,/[[:alnum:]_]+\.LIB/);
print substr(s,RSTART,RLENGTH)
}' file
这仅使用普通的旧 awk 函数 match()
和 substr()
来 (1) 剥离第一个 .LIB
并将该行的其余部分存储在一个临时变量中, (2) 在该变量中找到下一个 .LIB
。
它的优点是不依赖于事物的任何特定位置——即它不假设 "interesting" 文件紧跟在第一个文件之后,或者是行中的倒数第二个文件等
也就是说,这很麻烦,anubhava 的第二个解决方案要优雅得多。 :-)
让我以我在 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。
我尝试将 gawk 与 match() 函数一起使用,并将我的匹配项存储在一个数组中,但似乎我不能使用 match() "match() cannot have 3 arguments" 的第三个参数。我们的 gawk 版本是 3.0.3。是的。我在玩 perl,试图让它在命令行设置中工作。我们的 perl 版本是 5.8.7。如果您的答案包括 grep 中的一些奇特的新选项,您也可以认为 grep 的 QSH 版本同样古老,尽管有 PASE 实用程序,如果您知道它们是什么的话。
我还在努力解决这个问题,但我很可能很快就会头疼,因此请提供任何建议。 :-)
您可能需要 last-1 片段。以下 awk
应该有效:
awk -F/ '{print $(NF-1)}' file
KDBDFC1_5.LIB
FPSENGDEV.LIB
或者这个 awk
可能会通过搜索 .LIB
并打印第二个字段来工作:
awk -F'.LIB' '{print substr(,2) FS}' file
KDBDFC1_5.LIB
FPSENGDEV.LIB
怎么样
perl -lne '@matches = /(\w+\.LIB)/g; print $matches[1] if @matches > 1' file
return second
出现 <word>.LIB
:
perl -pe 's/^(?:.*?\.LIB).*?([\w_.]*.LIB).*$//g'
return <word>.LIB
的 last
出现 :
perl -pe 's/^(?:.*\.LIB).*?([\w_.]*.LIB).*$//g' file
^
开始于
(?:.*\.LIB)
正在取消捕获包含 .LIB 的组
.*?
有什么不满意的地方
([\w.]*.LIB)
第一个捕获组 <word>.LIB
.*
什么都贪心
$
完成
如果match
不支持数组输出,你可以运行匹配两次,丢弃第一个匹配,打印第二个:
$ awk '{p="[a-zA-Z0-9_]*.LIB"; sub(p,""); match([=10=],p); print substr([=10=],RSTART,RLENGTH)}' file
KDBDFC1_5.LIB
FPSENGDEV.LIB
所以...在搜索正则表达式中添加下划线后,以下对我有用:
sed 's/.*\/\([[:alnum:]_]*\.LIB\).*//' 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
文件中的 second,这可能会:
awk '{match([=13=],/[[:alnum:]_]+\.LIB/); s=substr([=13=],RSTART+RLENGTH); match(s,/[[:alnum:]_]+\.LIB/); print substr(s,RSTART,RLENGTH)}' file
或者,为了便于阅读,拆分为:
awk '{
match([=14=],/[[:alnum:]_]+\.LIB/);
s=substr([=14=],RSTART+RLENGTH);
match(s,/[[:alnum:]_]+\.LIB/);
print substr(s,RSTART,RLENGTH)
}' file
这仅使用普通的旧 awk 函数 match()
和 substr()
来 (1) 剥离第一个 .LIB
并将该行的其余部分存储在一个临时变量中, (2) 在该变量中找到下一个 .LIB
。
它的优点是不依赖于事物的任何特定位置——即它不假设 "interesting" 文件紧跟在第一个文件之后,或者是行中的倒数第二个文件等
也就是说,这很麻烦,anubhava 的第二个解决方案要优雅得多。 :-)