我试图弄清楚为什么这不起作用,当然如何解决它,我在变量中有很长的日期列表,并且想要使用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
有什么想法吗?
答案 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