有一堆与此类似的文本(为了测试和使数据尽可能简单):
first 1 is the real 2 time the word matched 3
appeared on the previous line but is 4 the fourth.
Every line can have more numbers 5 because numbers 6 are everywhere
I need to extract the number just after the word 7 that precedes 8
grep
我正在测试提取单词后面数字的第一个匹配项的命令是:
grep -Eoi ' [0-9]{1}'
输出是:
1
2
3
4
5
6
7
8
期望的输出是:
1
4
5
7
不允许使用cut
也不awk
。
答案1
我怀疑这是一种仅掌握 grep 的练习。纯 grep 解决方案是这样的:
在一行中:
echo "first 1 is the real 2 time the word matched 3 " |grep -Eo '[0-9]' |grep -m1 -E '[0-9]'
不幸的是,在第一个 grep 中使用grep -m1
并没有给出所需的结果。
在包含多行的文件中,您必须使用循环:
while read -r line; do
grep -Eo '[0-9]' <<<"$line" |grep -m1 -E '[0-9]'
done < file.txt
或者在一个命令行中:
while read -r line; do grep -Eo '[0-9]' <<<"$line" |grep -m1 -E '[0-9]';done < a.txt
输出如所期望。
答案2
你被允许使用吗sed
?
$ sed 's/[^[[:digit:]]*\([[:digit:]]\).*/\1/' << EOF
> first 1 is the real 2 time the word matched 3
> appeared on the previous line but is 4 the fourth.
> Every line can have more numbers 5 because numbers 6 are everywhere
> I need to extract the number just after the word 7 that precedes 8
> EOF
1
4
5
7
答案3
你可以使用二 grep
命令,首先匹配并返回第一个十进制数字序列之前的所有内容,然后匹配并仅返回数字:
grep -Eo '^[^0-9]*[0-9]{1,}' file | grep -Eo '[0-9]{1,}'
[注意:我之所以使用,{1,}
是因为 AFAIK{1}
是多余的,并且我假设您想要匹配十进制序列。]
如果您被允许使用 PCRE 模式,并且您支持它,则可以通过使用可变宽度后向断言grep
在单个 中有效地执行相同的操作:grep
\K
grep -Po '^[^0-9]*\K[0-9]+' file
或者(稍微更紧凑,使用 perl 样式\d
表示十进制数字):
grep -Po '^[^\d]*\K\d+' file
或者说,自从你不说你不是允许使用perl
自身,您可以分成空格分隔的字段,然后找到第一个全数字字段:
perl -MList::Util=first -alne 'print first { /^\d+$/ } @F'
答案4
你可以试试这个:
grep -Eon ' [0-9]{1}' | sort -k1,1 -u
输出如下(不确定行号是否会破坏交易):
1: 1
2: 4
3: 5
4: 7
或者,此表达式将为您提供所需的输出:
grep -Eon ' [0-9]{1}' | sort -k1,1 -u | grep -o ' .*'
输出(您的输出示例包括前导空格):
1
4
5
7