grep 输出格式为文件名和匹配行之间的间距?

grep 输出格式为文件名和匹配行之间的间距?

如何在文件名和匹配行之间添加空格?当您对许多文件运行“grep”时,看起来 grep 使用“-”或“:”(表示数字或字符串?)作为文件名和行之间的分隔符。因此,根据行的不同,分隔符可以与第一个字符连接或与其分隔。如何才能使这一点在后续工作中保持一致。在连续的工作中,我想使用“awk”获取同一列上的数字。详细情况是这样的。

文件可以这样写,第一列看起来是一个右对齐的 5 位数字。根据循环的结束条件,循环的最后一行可能会有所不同。我使用下一行“...optimization bla bla”找到循环的最后一行。

文件的情况1

 9969 2020-11-23T14:20:09   6.7433e-02 1.0544e-03 - 2.1166e-03 C 1.2973e-01 - 1.4468e+00 C
...optimization unsuccessful. 

另一个文件的情况2

10072 2020-11-23T14:30:48   6.7384e-02 1.0569e-03 - 2.1148e-03 C 1.2968e-01 - 1.4539e+00 C
...optimization unsuccessful.

我想使用“awk”获取 8 美元的数字,即第 8 个值。然后我跑

grep "optimization un" */log.txt -B 1

输出是

NN14/log.txt- 5015 2020-11-21T00:13:37   7.4772e-02 9.5215e-04 - 2.2506e-03 C 1.3664e-01 - 1.2459e+00 C
NN14/log.txt:...optimization unsuccessful. 392.1 min.
NN18/log.txt-10080 2020-11-23T22:41:12   6.5363e-02 9.1362e-04 - 2.4192e-03 C 1.2775e-01 - 1.3058e+00 C
NN18/log.txt:...optimization unsuccessful. 1517.2 min.

然后我想使用获取号码

grep "optimization un" */log.txt -B 1 | awk '/T/ {print $8}'

那么结果就变成了

C
1.2775e-01

因此,我想将“NN14/log.txt-5015”和“NN18/log.txt-10080”更改为相同的格式,带或不带空格。如何做呢?或者还有其他办法吗?我尝试使用 -T 表示制表符,但分隔符附加到行侧而不是文件名侧,因此它无效。

答案1

Meta:在评论中解释太多,但不是所问问题的答案。

我不知道你所说的“请注意,首先它需要在文件中间的顺序编号中找到最后一行”是什么意思。您显示的命令选择包含字符串“optimization un”的行之前的行(如果它还包含字母“T”);在您显示的数据中,这一行包含一些数字,实际上这些数字中的一个或多个可能是连续的,但您的选择与连续的数字甚至是数字无关;您的选择仅基于字符串和字母。

您正在 grep 多个文件,*/log.txt因此默认grep 输出以文件名和破折号或冒号开始每一行。 (这与“数字或字符串”无关;它使用冒号作为行匹配正则表达式和行的破折号或者-B由于选项(您使用的)或.)而包含的匹配-A。但是由于冒号或破折号都不是空格,如果该行有时像您一样以空格开头,这会影响awk使用空格的默认字段解析。 (awk字段解析被更改,但对于您的数据格式,我没有看到任何可以更好地工作的更改。)

但是您随后选择的awk行和字段不依赖于或包含文件名,因此如果您忽略它起作用的文件名。并grep -h省略文件名。尝试grep -h -B1 "optimization un" */log.txt(像这样的选项-h -B1应该位于正则表达式/模式和文件名之前,尽管 GNU grep 允许您将它们作为扩展名放在后面),您应该看到更像这样的数据:

 5015 2020-11-21T00:13:37   7.4772e-02 9.5215e-04 - 2.2506e-03 C 1.3664e-01 - 1.2459e+00 C
...optimization unsuccessful. 392.1 min.
10080 2020-11-23T22:41:12   6.5363e-02 9.1362e-04 - 2.4192e-03 C 1.2775e-01 - 1.3058e+00 C
...optimization unsuccessful. 1517.2 min.

(虽然 IME 你也应该有--分隔块的线,但你没有显示)(但如果存在,它们将被跳过awk并且无关紧要)。

如果你现在通过原来的管道| awk '/T/{print $8}'它应该可以工作。

grep但正如我所说,您根本不需要(及其格式),只需执行以下操作:

awk '/optimization un/{print x} {x=$8}' */log.txt

其中任何一个都应该解决您的问题,但都不能回答您提出的问题(在文件名和匹配行之间放置一个空格),因此根据堆栈策略,这不是有效的答案,应该删除。

答案2

如果无法将“:”或“-”等分隔符与行分开,则可以绕过来计算 awk 中的字段数。

grep "optimization un" */amp-log.txt -B 1 | awk '{if(NF==11) {print $8} else if(NF==12) {print $9} }'

然后得到:

1.3725e-01
1.3664e-01
1.2968e-01
1.2775e-01

不管 ”

NN12/log.txt- 5014 2020-11-20T23:34:02   7.5423e-02 8.5699e-04 - 2.2759e-03 C 1.3725e-01 - 1.1654e+00 C
NN16/amp-log.txt-10072 2020-11-23T14:30:48   6.7384e-02 1.0569e-03 - 2.1148e-03 C 1.2968e-01 - 1.4539e+00 C

相关内容