如何仅打印两个匹配列之间的列值

如何仅打印两个匹配列之间的列值

我有一个/tmp/ggloc.log包含以下数据的文件

$ cat /tmp/ggloc.log
oracle    12061      1  1 Sep08 ?        10:44:07 ./mgr PARAMFILE /oracle/gg/dirprm/mgr.prm REPORTFILE /oracle/gg/dirrpt/MGR.rpt PROCESSID MGR USESUBDIRS
oracle    75841  75810  0 13:55 ?        00:00:00 grep -i mgr
postfix  103283 103268  0 Feb24 ?        00:02:18 qmgr -l -t unix -u
oracle   185935      1  0 Sep08 ?        00:14:14 ./mgr PARAMFILE /oracle/GG_123012/GG_HOME/dirprm/mgr.prm REPORTFILE /oracle/GG_123012/GG_HOME/dirrpt/MGR.rpt PROCESSID MGR

所以从上面的文件中,我想要下面的输出

/oracle/gg
/oracle/GG_123012/GG_HOME

我试过如下

k=$(cat /tmp/ggloc.log)
echo "$k" | sed 's/.*PARAMFILE \(.*\) REPORTFILE.*/\1/' | awk -F "/dirprm" '{print $1}'

我的输出低于

/oracle/gg
oracle    75841  75810  0 13:55 ?        00:00:00 grep -i mgr
postfix  103283 103268  0 Feb24 ?        00:02:18 qmgr -l -t unix -u
/oracle/GG_123012/GG_HOME

那么我怎样才能只得到

/oracle/gg
/oracle/GG_123012/GG_HOME

需要您的投入

答案1

思考您想要找到包含该单词的行PARAMFILE,然后打印后面的最长字符串PARAMFILE和一个空格,直到最后一个/dirprm。如果是这样,您可以尝试:

$ sed -En 's/.*PARAMFILE (.*)\/dirprm.*/\1/p' file
/oracle/gg
/oracle/GG_123012/GG_HOME

或者,如果您sed不支持-E

$ sed -n 's/.*PARAMFILE \(.*\)\/dirprm.*/\1/p' file
/oracle/gg
/oracle/GG_123012/GG_HOME

甚至

$ awk '$9=="PARAMFILE"{sub("/dirprm.*","",$10); print $10}' file
/oracle/gg
/oracle/GG_123012/GG_HOME

或者,如果您想要的是第一个而不是最后一个/dirpm

$ perl -lne 'print $1 if s/.*PARAMFILE (.*?)\/dirprm.*/\1/' file
/oracle/gg
/oracle/GG_123012/GG_HOME

答案2

您可以grep通过以下选项使用 GNU 来完成任务-P

$ grep -oP '(?<=PARAMFILE ).*(?=/dirprm)' /tmp/ggloc.log 
/oracle/gg
/oracle/GG_123012/GG_HOME

答案3

如果您对使用正则表达式不太感兴趣,这是另一个有用的解决方案:

grep PARAMFILE file | tr -s ' ' | cut -f10 -d' '

grep只会给你包含 PARAMFILE 的行。 tr会将所有空间压缩为一个。最后cut只会给出该行中的第十个单词。

更新:正如评论中指出的那样 - 第一个命令不会删除字符串中不需要的尾部。所以这是一个更正的版本:

grep PARAMFILE q | tr -s ' ' | cut -f10 -d' '| sed 's/\/dirprm\/mgr.prm//'

抱歉,我不知道如何避免明显使用正则表达式。

相关内容