我想使用sed转换文件。源文件具有以下格式(' deviceId'是占位符):
CREATE DATABASE "deviceId";
column value=88i 1445137680000000000
column value=68i 1445137620000000000
column value=80i 1445137560000000000
column value=39i 1445137500000000000
转换后,它应具有以下格式:
USE DATABASE "db";
series,device=deviceId column=88i 1445137680000000000
series,device=deviceId column=68i 1445137620000000000
series,device=deviceId column=80i 1445137560000000000
series,device=deviceId column=39i 1445137500000000000
但是我不知道,我怎样才能在每一行中获得deviceId。我当前的sed.txt
包含以下代码:
s/^\(CREATE DATABASE ".*";\)$/USE DATABASE "db";/g
s/\(.*\) .*=\(.*\) \(.*\)/series,device= \1=\2 \3/g
并生成以下输出:
USE DATABASE "db";
series,device= column=88i 1445137680000000000·
series,device= column=68i 1445137620000000000
series,device= column=80i 1445137560000000000
series,device= column=39i 1445137500000000000
有人可以解释我如何在每一行获得deviceId?我已经看到它可能使用Hold-Space / Flow-Work。我试过了,但我不知道这应该如何工作。
谢谢!
答案 0 :(得分:0)
试试这个。
#!/usr/bin/perl
use strict;
use warnings;
my $deviceId = "";
while( my $line = <STDIN>) {
chomp($line);
if($line =~ m/CREATE DATABASE/) {
$deviceId = $line;
$deviceId =~ s/CREATE DATABASE "(.*)"/$1/;
print('USE DATABASE "db";' . "\n");
}
else {
$line =~ s/(.*) .*=(.*) (.*)/series,device=$deviceId $1=$2 $3\n/g;
print($line);
}
}
答案 1 :(得分:0)
您尝试使用错误的工具。虽然你可以,我想,想出一些神奇的符文来强制sed产生你想要的输出,因为它具有健壮性,可移植性,简单性,效率以及几乎所有其他理想的软件属性,这是用于其他任何事情的标准UNIX工具。而不是单个行上的简单替换是awk:
$ awk -F'["=]' '
NR==1{dev=$(NF-1); $0 = "USE DATABASE \"db\""}
NR>1 {$0 = "series,device=" dev " column=" $2}
1' file
USE DATABASE "db"
series,device=deviceId column=88i 1445137680000000000
series,device=deviceId column=68i 1445137620000000000
series,device=deviceId column=80i 1445137560000000000
series,device=deviceId column=39i 1445137500000000000
答案 2 :(得分:0)
这可能适合你(GNU sed):
sed -re '1h;1cUSE DATABASE "db";' -e 'G;s/.*value(.*)\n.*"(.*)".*/series,device=\2 column\1/' file
这将第一行存储在保留空间(HS)中。将第一行更改为所需格式。然后在第一行之后的每一行:追加存储的第一行,并使用模式匹配和反向引用将该行按照所需格式进行按摩。
答案 3 :(得分:0)
我不经常使用保持缓冲区,所以我想为练习提供一个sed解决方案:
/^CREATE/ {
# strip everything surrounding deviceId
s/[^"]*"\([^"]*\).*/\1/
# copy to the hold buffer
h
# replace pattern buffer with USE ...
s/.*/USE DATABASE "db";/
}
/^column/ {
# append the hold space to the pattern buffer
# this adds a leading newline which we'll use to capture deviceId
G
# capture the 1st field, value of the 2nd, the 3rd field,
# then the appended deviceId after the newline
s/\([^ ]*\) .*=\([^ ]*\) \(.*\)\n\(.*\)/series,device=\4 \1=\2 \3/
}