如何捕获最右边的字符串?

时间:2015-06-26 11:31:32

标签: regex bash awk sed

我有不同的环境。在每个环境中,日志位于不同的路径中。 e.g:

/u01/../etc/apps/../def-20150626044921.log 
/u01/log02/../etc/apps/../mno-20150626071656.log 
/u02/../etc/apps/../xyz-20150626044921.log

我试图在.log之前抓取最右边的数字并以YYYY-MM-DD HH:MM:SS格式显示它们。

在不同的组合中使用这些我可以单独得到结果。例如:

sed "s/01//"; 
sed "s/[^0-9]*//g"; 
sed "s/(.{4})(.{2})(.{2})/\1-\2-\3 /", 
sed "s/(.{10})(.{3})(.{2})/\1 \2:\3:/";

我的要求是在脚本中添加命令。但是,当路径不同时,我无法获得结果。就像代替u01而不是u02命令一样无效。

基本上我只需要在.log之前捕获YYYYMMDDHHMMSS并删除其他所有内容。有没有办法使命令动态,因此它独立于日志路径,并且无论日志位于何处都无关紧要,它将始终以所需格式显示日期和时间。

感谢您查看问题...... !!

5 个答案:

答案 0 :(得分:3)

您可以在不启动bash的情况下使用sed参数替换:

x="/u02/../etc/apps/../xyz-20150626044921.log"
d1=${x%.log}    # strip ".log"
d2=${d1##*-}    # strip everything up to dash

echo $d2
20150626044921

示例和详细信息为here

答案 1 :(得分:2)

试试这个:

sed 's/.*\([0-9]\{4\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{2\}\).log$/\1-\2-\3 \4:\5:\6/' infile

说明:

  • .*匹配所有内容,直到第一个数字,我们不会捕获,因为我们不需要它。
  • \([0-9]\{4\}\)捕获年份
  • 以下5次\([0-9]\{2\}\)次捕获月,日,时,分和秒。
  • .log$在我们与文件扩展名和行尾相匹配的号码之后,我们再次捕获这些号码,因为我们不需要它。
  • 然后我们使用所需的格式\1-\2-\3 \4:\5
  • 将它们分开

答案 2 :(得分:2)

$ sed -r 's/.*(....)(..)(..)(..)(..)(..)\.log$/\1-\2-\3 \4:\5:\6/' file
2015-06-26 04:49:21
2015-06-26 07:16:56
2015-06-26 04:49:21

或使用GNU awk for gensub():

$ gawk '{print gensub(/.*(....)(..)(..)(..)(..)(..)\.log$/,"\\1-\\2-\\3 \\4:\\5:\\6","")}' file
2015-06-26 04:49:21
2015-06-26 07:16:56
2015-06-26 04:49:21

或再次使用GNU awk,这次是第三个arg匹配():

$ gawk 'match($0,/(....)(..)(..)(..)(..)(..)\.log$/,a){print a[1]"-"a[2]"-"a[3]" "a[4]":"a[5]":"a[6]}' file
2015-06-26 04:49:21
2015-06-26 07:16:56
2015-06-26 04:49:21

如果您想要对输入中隔离的日期/时间部分执行任何其他操作(例如,添加或减去某些值或以其他方式修改其中的任何/所有值),那么最后一个特别有用,因为它存储了在数组(a[])中,与第一个gawk脚本和刚刚输出输入字符串的修改版本的sed脚本不同。例如:

$ echo "20150607120500" | gawk 'match($0,/(....)(..)(..)(..)(..)(..)/,a){time=a[4]":"a[5]":"a[6]; if (time=="12:00:00") time="noon"; print a[1]"-"a[2]"-"a[3], time}'
2015-06-07 12:05:00

$ echo "20150607120000" | gawk 'match($0,/(....)(..)(..)(..)(..)(..)/,a){time=a[4]":"a[5]":"a[6]; if (time=="12:00:00") time="noon"; print a[1]"-"a[2]"-"a[3], time}'
2015-06-07 noon

答案 3 :(得分:1)

使用awk

awk -F '[-\.]' '{a=$(NF-1); print substr(a,1,4) "-" substr(a,5,2) "-" substr(a,7,2) " " substr(a,9,2) ":" substr(a,11,2) ":" substr(a,13,2);}' filename

substr(a,i,j)将从a返回子字符串,从索引i开始,长度为j

我认为理解起来很简单。

答案 4 :(得分:0)

awk -F'[-.]' '{sub(/20150626/,"2015-06-26 ",$6)sub(/ 0./,"&:",$6)sub(/..$/,":&",$6);print $6}' file

2015-06-26 04:49:21
2015-06-26 07:16:56
2015-06-26 04:49:21