6

我试图返回多个字符串的第一次出现,即,我想从以下文本中选择第一次出现 1259、3009 和 1589 的行。

ADWN    1259    11:00   B23

ADWN    3009    12:00   B19

DDWN     723    11:30   B04

ADWN    1589    14:20   B12

ADWN    1259    11:10   B23

DDWN    2534    13:00   B16

ADWN    3009    11:50   B14

这给了我所有的比赛:

grep '1259\|3009\|1589'  somelog.log

这只给了我第一场比赛

grep -m 1  '1259\|3009\|1589'  somelog.log

我想返回以下内容:

ADWN    1259    11:00   B23

ADWN    3009    12:00   B19

ADWN    1589    14:20   B12

我认为创建具有所需值的文件,然后遍历文件,将每个数字单独传递给 grep 命令会给我我正在寻找的东西,但我还没有找到这样的例子。有没有一个简单的解决方案,循环是处理这个问题的最佳方法,还是这个例子已经在其他地方得到了回答?

提前感谢您的想法和建议-

克莱德

4

4 回答 4

4

一种使用方式awk

awk '!array[$2]++ && $2 ~ /^1259$|^3009$|^1589$/' file.txt

结果:

ADWN    1259    11:00   B23
ADWN    3009    12:00   B19
ADWN    1589    14:20   B12

编辑:

我真的应该养成先阅读整个问题的习惯。我看到您正在考虑使用您希望第一次出现的值创建一个文件。将它们放在一个名为的文件中values.txt,每行一个值。例如; 这是以下内容values.txt

1259
3009
1589

然后运行这个:

awk 'FNR==NR { array[$0]++; next } $2 in array { print; delete array[$2] }' values.txt file.txt

结果:

ADWN    1259    11:00   B23
ADWN    3009    12:00   B19
ADWN    1589    14:20   B12

第一条命令解释:

如果第二列 ( $2) 等于列出的这三个值之一,则将其添加到数组中(如果它尚不存在)。awk默认打印整行。

第二条命令解释:

FNR是相对于当前输入文件的记录数。
NR是记录的总数。

FNR==NR { ... }构造仅适用于第一个输入文件。因此,对于 中的每一行values.txt,我们将整行 ( $0) 添加到一个数组中(我称它为数组,但您可以给它另一个名称)。next强制awk读取下一行values.txt(并跳过处理命令的其余部分)。当FNR==NR不再为真时,将读取参数列表中的第二个文件。然后我们检查$2数组中的第二列 ( ),如果它在那里,打印它并将其从数组中删除。通过使用delete,我们基本上将最大计数设置为 1。

于 2012-11-03T00:58:33.067 回答
0

试试这个。根据您的 grep 版本,它可能不起作用:

 grep -m 1 -e pattern1 -e pattern2
于 2012-11-03T00:58:52.410 回答
0

您可以使用每个(请参阅Linux Shell Script For Each File in a Directory Grab the filename and execute a program)对于要匹配的每个模式,执行一个单独的 grep 连接到输出文件

于 2012-11-03T01:01:02.830 回答
0

这个也可以。

for i in $(cut -d " " -f1 somelog.log | sort -u); do LC_ALL=C fgrep -m1 "$i" somelog.log; done
于 2016-07-19T04:16:23.313 回答