How to *return* *only* the nth occurrence of a regex match using sed?
信息
我有一个包含时间信息的字符串。我只需要从该字符串中获取月数即可。我正在尝试使用
当前尝试
1 | echo"1969 years 12 months 25 days 19 hours 38 minutes 24 seconds since last release" | sed -r"s/^([0-9]+).*/\\1/" |
返回
奖金
更一般地说,我的问题是字符串的整个
编辑:我正在尝试从这篇文章中使用nunk的解决方案:
How to find the difference in days between two dates?
除了几个月之外,它适用于所有内容。月份数减少了(打印的12个月数)。
我接下来将要这样做:
1 2 3 4 5 6 | str="1969 years 12 months 25 days 19 hours 38 minutes 24 seconds since last release" read y m d H M S < <(echo $(grep -oP '\\d+' <<<"$str")) echo"month: $m" echo"year: $y" #etc for $d $H $M $S |
打印:
1 2 | month: 12 year: 1969 |
-
grep 过滤掉所有数字(每个数字单独一行) -
echo 用数字将空格分隔开 -
将读取
read 并将其分配给相应变量的每个数字
这件衣服是否适合:
1 | echo"1969 years 12 months 25 days 19 hours 38 minutes 24 seconds since last release" | sed -r 's/.* ([0-9]+) months.*/\\1/' |
给予
1 | 12 |
这是怎么回事:
-
如果按顺序满足以下所有条件,则表达式的"匹配"部分将成功:
-
.* 任何东西 -
一个空格 -
[0-9]+ 一个或多个数字(使用( 和) "捕获") -
另一个空格 -
months 单词" months" -
.* 任何东西
-
-
如果成功,则由于两端都是
.* ,因此可以保证匹配整行。 -
另外,如果成功,则匹配(整行)将替换为
\\1 ,这是一个特殊的代码,表示"第一组捕获括号的内容。您将看到上面括号捕获的值是单词" months"前面的数字。
您可以使用Perl来分离键值对:
1 2 3 4 5 6 7 8 | $ str="1969 years 12 months 25 days 19 hours 38 minutes 24 seconds since last release" $ echo $str | perl -lane 'print"$1 $2" while /(\\d+)\\s(\\w+)/g' 1969 years 12 months 25 days 19 hours 38 minutes 24 seconds |
然后使用grep抓取您想要的一个:
1 2 | $ echo $str | perl -lane 'print"$1 $2" while /(\\d+)\\s(\\w+)/g' | grep 'months' 12 months |
听起来您正在尝试通过运行有问题的工具来修正输出来区分日期。只需使用GNU awk代替:
1 2 3 | $ echo"2014-09-03T14:44:48+00:00" | gawk '{gsub(/[-T:+]/,""); print (systime() - mktime($0)) / (24*60*60)}' 5.86991 |
根据输出天数进行任意舍入,例如:
1 2 3 4 | $ echo"2014-09-03T14:44:48+00:00" | gawk '{gsub(/[-T:+]/,""); printf"%.0f\ ", (systime() - mktime($0)) / (24*60*60)}' 6 |
请注意,使用"%.0f"进行舍入的实现取决于系统-可能舍入0.5或将其舍入到最接近的偶数。如果这是一个问题,请检查系统并在必要时编写自己的舍入函数。