sed将行的第一部分复制到同一行的多个位置

时间:2013-12-21 21:19:15

标签: replace sed

我有一种感觉,我想要做的事情非常简单,但我的大脑却没有想出正确的方法来操纵它。有一个包含数千行的文件,每个行都有一个开始部分(日期和时间戳),然后是一组或多组值(包括MAC地址,IP地址和用户名)。我希望使用sed来获取第一部分并将其复制到每行值的开头。这是一个例子:

源文件的内容:

2013-08-02 11:33:32 (00:11:22:33:44:55, 10.8.12.13, ajones) (12:23:34:45:56:67, 10.8.23.34, msmith) (23:34:45:56:67:78, 10.8.44.33, hjohnson)
2014-09-22 14:43:02 (33:44:55:66:77:88, 10.8.98.99, brodriguez)
2015-10-31 04:43:39 (a2:4b:77:3c:32:91, 10.8.100.55, sthomas) (05:71:38:65:c4:7a, 10.8.81.43, ymcalister)

会变成:

2013-08-02 11:33:32 (00:11:22:33:44:55, 10.8.12.13, ajones)
2013-08-02 11:33:32 (12:23:34:45:56:67, 10.8.23.34, msmith)
2013-08-02 11:33:32 (23:34:45:56:67:78, 10.8.44.33, hjohnson)
2014-09-22 14:43:02 (33:44:55:66:77:88, 10.8.98.99, brodriguez)
2015-10-31 04:43:39 (a2:4b:77:3c:32:91, 10.8.100.55, sthomas)
2015-10-31 04:43:39 (05:71:38:65:c4:7a, 10.8.81.43, ymcalister)

我一直在使用保持空间来处理线路上的全局替换,但我找不到一种方法来将保持内容作为替换参数,这将使这更容易。再说一次,我确信有一些非常基本的东西,我没有做,但对于我的生活,我无法理解。感谢您提供任何帮助!

3 个答案:

答案 0 :(得分:1)

不确定如何使用sed执行此操作,但使用awk可以执行此操作:

awk -F\( '{for (i=2;i<=NF;i++) print $1 FS $i}' file
2013-08-02 11:33:32 (00:11:22:33:44:55, 10.8.12.13, ajones)
2013-08-02 11:33:32 (12:23:34:45:56:67, 10.8.23.34, msmith)
2013-08-02 11:33:32 (23:34:45:56:67:78, 10.8.44.33, hjohnson)
2014-09-22 14:43:02 (33:44:55:66:77:88, 10.8.98.99, brodriguez)
2015-10-31 04:43:39 (a2:4b:77:3c:32:91, 10.8.100.55, sthomas)
2015-10-31 04:43:39 (05:71:38:65:c4:7a, 10.8.81.43, ymcalister)

我将字段分隔符设置为(然后为所有字段打印第一个字段,然后在循环中打印到结尾。

答案 1 :(得分:1)

这可能适合你(GNU sed):

sed -r 's/^(\S+ \S+) \([^)]*\)/&\n\1/;/\(/P;D' file

答案 2 :(得分:0)

使用D命令设置递归循环。我们基本上将日期存储在保留空间中,然后在打印信息之前将其打印出来。如果一行中有多条信息,我们会在信息末尾插入换行符,将其打印出来,然后删除除D之前的所有内容,这也会重新开始循环。

/[[:date:]]/ { x; d; g; s/\([[:date:]]\) .*/\1/; x; s/[[:date:]] \(.*\)/\1/ }
x; p; x
s/[[:info:]]/&\n/
P
D

其中[[:date:]][[:info:]]分别是日期和信息的正则表达式。