Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux SED-保留空间-所有行都有一个值_Linux_Bash_Text_Sed_Sh - Fatal编程技术网

Linux SED-保留空间-所有行都有一个值

Linux SED-保留空间-所有行都有一个值,linux,bash,text,sed,sh,Linux,Bash,Text,Sed,Sh,我想使用sed转换文件。源文件具有以下格式(“deviceId”是占位符): 创建数据库“deviceId”; 列值=88i 144513768000000 列值=68i 14451376200000000 列值=80i 1445137560000000 列值=39i 1445137500000000 转换后,应具有以下格式: 使用数据库“db”; 系列,设备=deviceId列=88i 144513768000000 系列,设备=deviceId列=68i 14451376200000000

我想使用sed转换文件。源文件具有以下格式(“deviceId”是占位符):

创建数据库“deviceId”;
列值=88i 144513768000000
列值=68i 14451376200000000
列值=80i 1445137560000000
列值=39i 1445137500000000
转换后,应具有以下格式:

使用数据库“db”;
系列,设备=deviceId列=88i 144513768000000
系列,设备=deviceId列=68i 14451376200000000
系列,设备=deviceId列=80i 1445137560000000
系列,设备=deviceId列=39i 1445137500000000
但是我不明白,我怎样才能在每一行中都得到设备ID。我当前的
sed.txt
包含以下代码:

s/^\(创建数据库“*”;\)$/使用数据库“db”/G
s/\(.*\).=\(.*\)\(.*\)/系列,设备=\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
有人能解释一下我是如何在每一行中获得设备ID的吗?我已经看到了使用保持空间/流动工作的可能性。我已经试过了,但我不知道该怎么做

谢谢大家!

试试这个

#!/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);
  }
}
#/usr/bin/perl
严格使用;
使用警告;
我的$deviceId=“”;
while(我的$line=){
chomp($line);
如果($line=~m/CREATE DATABASE/){
$deviceId=$line;
$deviceId=~s/创建数据库“(.*)”/$1/;
打印('使用数据库“db”'。“\n”);
}
否则{
$line=~s/(.*)。*=(.*)(.*)/系列,device=$deviceId$1=$2$3\n/g;
打印(行);
}
}

您试图使用错误的工具。我希望你能想出一些神奇的符文来迫使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
这可能适用于您(GNU-sed):


这将在保持空间(HS)中存储第一行。将第一行更改为所需格式。然后在第一行之后的每一行上:追加存储的第一行,并使用模式匹配和反向引用将该行转换为所需的格式。

我不经常使用保持缓冲区,因此我想为实践提供一个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/
}

谢谢,但那不是我需要的
\3
只是当前行的时间戳。我需要的是第一行的deviceId。是否需要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/
}