使用grep解析多行变量

时间:2015-11-27 10:43:29

标签: linux bash sed grep tr

我试图弄清楚为什么这不起作用,当然如何解决它,我在变量中有很长的日期列表,并且想要使用grep计算出现次数,看起来像是拆分一个变量新线路不能按预期工作?例如,

$ list="2015-a 2015-b 2016-a" ; count=`echo $list | tr " " \\n | grep 2015 | wc -l` ; echo $count
1


$ list="2015-a,2015-b,2016-a" ; count=`echo $list | tr , \\n | grep 2015 | wc -l` ; echo $count
1


$ list="2015-a,2015-b,2016-a" ; count=`echo $list | sed s/,/\\n/g | grep 2015 | wc -l` ; echo $count
1

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

问题在于反引号解释\\的方式:

  

反引号内的反斜杠()以非显而易见的方式处理:

  $ echo "`echo \\a`" "$(echo \\a)"
  a \a
  $ echo "`echo \\\\a`" "$(echo \\\\a)"
  \a \\a
  # Note that this is true for *single quotes* too!
  $ foo=`echo '\\'`; bar=$(echo '\\'); echo "foo is $foo, bar is $bar" 
  foo is \, bar is \\

所以不要说:

$ echo "`echo $list | tr " " \\n`"
2015-an2015-bn2016-a

你必须说:

$ echo "`echo $list | tr " " \\\\n`"
2015-a
2015-b
2016-a

尽管最好使用$(),因为不推荐使用反引号:

$ echo "$(echo $list | tr " " '\n')"
2015-a
2015-b
2016-a

如果您仍想使用反引号,最干净的解决方案是使用" "作为包装,而不是使用\\\\转义:

$  echo "`echo $list | tr " " "\n"`"
2015-a
2015-b
2016-a

所有这些都可以在Why is $(...) preferred over ... (backticks)?中阅读。

总而言之,如果您只想计算包含2015的单词数量,您可以考虑使用评论中建议的grep -o,或者像awk这样更强大的内容:< / p>

awk '{for (i=1;i<=NF;i++) if ($i~2015) count++; print count}'

参见一些例子:

$ awk '{for (i=1;i<=NF;i++) if ($i~2015) s++; print s}' <<< "2015-a 2015-b 2016-a"               2
$ awk '{for (i=1;i<=NF;i++) if ($i~2015) s++; print s}' <<< "2015-a 2015-b 2016-a 20152015-c"
3