显示包含一个且仅一个一位数字的行

时间:2015-12-06 22:36:52

标签: bash grep

使用grep,如何匹配包含一个但只有一位数字的行?

输入文件示例:

    SHELL=/bin/sh
    PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

    # m h dom mon dow user  command
    17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
    25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
    47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
    52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
    #

输出应为:

25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )

3 个答案:

答案 0 :(得分:0)

使用GNU grep:

grep '\b[0-9]\b' file | grep -v '\b[0-9]\b.*\b[0-9]\b'

输出:

    25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )

答案 1 :(得分:0)

要在仅包含一个数字且仅包含一个数字的文件中grep行

这样做

grep -P '^\D*\d\D*$' file

-P标志用于制作Perl表达式

http://www.gnu.org/software/grep/manual/grep.html

表达式本身是正则表达式

'^\D*\d\D*$'

'^'   = 'start of a line'
'\D*' = '0 or more non-digits'
'\d'  = '1 digit'
'\D*' = '0 or more non-digits'
'$'   = 'End of line'


<小时/>
更新:

即使回答并接受了这个问题,这个解决方案也可以帮助那些碰到这个问题的人。

正如TomZych在评论中所提到的,P是实验性的,所以我用E切换它,它是--extended-expression。

标题改变后,我之前的答案不是OP想要的。 所以这是新的表达式:

 grep -E '^([^0-9]|[0-9]{2,})*([0-9][^0-9]*)([^0-9]|[0-9]{2,})*$' file

表达解释

'^' # start of line


我们从第一组开始。

([^0-9]|[0-9]{2,})* # The first group:

'( ... )' # what ever is inside the parantheses is in the group.
'*'       # means repeat this expression zero or more times.

'[^0-9]', '[0-9]' # means all digits from 0-9, but the 
'^'       # means NOT when its in the squared brackets.
'{2,}'    # means this expression 2 or more times
'|'       # means OR

# So what we want here is:
# Zero or more, (non-digits characters or two or more digits numbers)

# This will match anything untill we meet a single digit number.



然后是第二组。

([0-9][^0-9]*) # second group:

# Here we want to match a single digit
'[0-9]'
# Followed by zero or more non-digits
'[^0-9]'

# This will match the single digit, the first group ran into.
# I use zero or more incase its the end of the line.


那么3.组实际上是第一组,零次或多次。

# Followed by 
'$' # End of line


这将匹配任何只有一位数字的行。

1 abc 123
abc 1 123
abc 123 1
abc 1 abc
123 1 123
abc1abc

# will all match

答案 2 :(得分:0)

这将匹配一位数字(SDN),只要它不在 行的开头或结尾:

[^0-9][0-9][^0-9]

所以,一个脆弱的解决方案是:

cat input |
grep '[^0-9][0-9][^0-9]' |
grep -v '[^0-9][0-9][^0-9].*[^0-9][0-9][^0-9]'

(这里,cat input代表任何管道数据到其余部分。 您还可以为grep提供文件名。)

第一个grep捕获具有一个或多个SDN的行,第二个捕获 一个人排除了一个以上的人。

然而,它将无法注意到SDN的开头或结尾 线,可以错过线条,包括我们不想要的线条。一个简单的 解决方案是临时在每行的每一端添加一个字符。

cat input |
sed -r 's/(.*)/x\1x/' |
grep '[^0-9][0-9][^0-9]' |
grep -v '[^0-9][0-9][^0-9].*[^0-9][0-9][^0-9]' |
sed -r 's/^x(.*)x$/\1/'