如何在文件名和匹配行之间添加空格?当您对许多文件运行“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