Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.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_Shell_Sed_Grep - Fatal编程技术网

Linux sed在每行重复字符串

Linux sed在每行重复字符串,linux,bash,shell,sed,grep,Linux,Bash,Shell,Sed,Grep,我有一个包含数百行的文件inventory.txt。它列出了与客户ID/名称、库存ID/名称和产品ID/名称相关的数据。文件的常规设置,在任何给定行上都可能出现acustomerId=123。在这一行之后,将出现一个inventoryId=abc行。此文件的外观如下所示: <> START OF FILE Customer ID=9000, Customer Name=Acme, Inc Inventory ID=INV_ID1, Inventory Name=Acme_INV1 P

我有一个包含数百行的文件
inventory.txt
。它列出了与客户ID/名称、库存ID/名称和产品ID/名称相关的数据。文件的常规设置,在任何给定行上都可能出现a
customerId=123
。在这一行之后,将出现一个
inventoryId=abc
行。此文件的外观如下所示:

<> START OF FILE
Customer ID=9000, Customer Name=Acme, Inc
Inventory ID=INV_ID1, Inventory Name=Acme_INV1
Product ID=100, Product Name=Banana
Product ID=200, Product Name=Apple
Inventory ID=INV_ID2, Inventory Name=Acme_INV2
Product ID=100, Product Name=Banana
Product ID=300, Product Name=Kiwi
Customer ID=7500, Customer Name=Anvil, Corp
Inventory ID=INV_ID3, Inventory Name=Anvil_INV1
Product ID=200, Product Name=Apple
<> END OF FILE
我知道如何使用SED将输入数据格式化为带有逗号和引号的CSV文件输出,但我很难弄清楚如何强制
客户ID
客户名称
在每个
库存ID
库存名称
行的开头重复

#!/usr/bin/perl
use warnings;
use strict;
use feature qw(say);

my ($customer, $name);
while (<>) {
    if (/Customer ID=(.*), Customer Name=(.*)/) {
        ($customer, $name) = ($1, $2);
    } elsif (/Inventory ID=(.*), Inventory Name=(.*)/) {
        say join ', ' => map qq("$_"), $customer, $name, $1, $2;
    }
}
sed -n '/^Customer ID/ h; /^Inventory ID/ { G; s/.*=\([^,]*\).*=\([^\n]*\).*=\([^,]*\).*=\(.*\)/"\3", "\4", "\1", "\2"/; p }' inventory.txt
#/usr/bin/perl
使用警告;
严格使用;
使用特征qw(例如);
我的($customer,$name);
而(){
如果(/Customer ID=(.*),则客户名称=(.*)/){
($customer,$name)=($1,$2);
}elsif(/Inventory ID=(*),Inventory Name=(.*)/){
说加入“,”=>MapQQ($),$customer,$name,$1,$2;
}
}
Perl解决方案:

#!/usr/bin/perl
use warnings;
use strict;
use feature qw(say);

my ($customer, $name);
while (<>) {
    if (/Customer ID=(.*), Customer Name=(.*)/) {
        ($customer, $name) = ($1, $2);
    } elsif (/Inventory ID=(.*), Inventory Name=(.*)/) {
        say join ', ' => map qq("$_"), $customer, $name, $1, $2;
    }
}
sed -n '/^Customer ID/ h; /^Inventory ID/ { G; s/.*=\([^,]*\).*=\([^\n]*\).*=\([^,]*\).*=\(.*\)/"\3", "\4", "\1", "\2"/; p }' inventory.txt
#/usr/bin/perl
使用警告;
严格使用;
使用特征qw(例如);
我的($customer,$name);
而(){
如果(/Customer ID=(.*),则客户名称=(.*)/){
($customer,$name)=($1,$2);
}elsif(/Inventory ID=(*),Inventory Name=(.*)/){
说加入“,”=>MapQQ($),$customer,$name,$1,$2;
}
}

这里有一种方法可以使用
awk

awk -F= '{ sub(/,.*/,"",$2) } /^Customer ID/ { r = $2 OFS $3 } /^Inventory ID/ { print "\"" r, $2, $3 "\"" }' OFS="\", \"" inventory.txt
sed
解决方案:

#!/usr/bin/perl
use warnings;
use strict;
use feature qw(say);

my ($customer, $name);
while (<>) {
    if (/Customer ID=(.*), Customer Name=(.*)/) {
        ($customer, $name) = ($1, $2);
    } elsif (/Inventory ID=(.*), Inventory Name=(.*)/) {
        say join ', ' => map qq("$_"), $customer, $name, $1, $2;
    }
}
sed -n '/^Customer ID/ h; /^Inventory ID/ { G; s/.*=\([^,]*\).*=\([^\n]*\).*=\([^,]*\).*=\(.*\)/"\3", "\4", "\1", "\2"/; p }' inventory.txt
结果:

"9000", "Acme, Inc", "INV_ID1", "Acme_INV1"
"9000", "Acme, Inc", "INV_ID2", "Acme_INV2"
"7500", "Anvil, Corp", "INV_ID3", "Anvil_INV1"

awk
说明:

 OFS="\", \""          # set the output field separator to: ", "

-F=                    # split the line into three fields using the '=' character

{ sub(/,.*/,"",$2) }   # one each line of input, remove everything trailing a
                       # comma from field two.

/^Customer ID/ { ... } # if the line starts with 'Customer ID'; do

r = $2 OFS $3          # build a record using field two and three separated by 'OFS'

/^Inventory ID/ {...}  # if the line starts with 'Inventory ID'; do

print "\"" r, $2, $3 "\""   # print out a double-quote, the record, OFS, $2, OFS, 
                            # $3 and lastly a double quote
sed
说明:

 OFS="\", \""          # set the output field separator to: ", "

-F=                    # split the line into three fields using the '=' character

{ sub(/,.*/,"",$2) }   # one each line of input, remove everything trailing a
                       # comma from field two.

/^Customer ID/ { ... } # if the line starts with 'Customer ID'; do

r = $2 OFS $3          # build a record using field two and three separated by 'OFS'

/^Inventory ID/ {...}  # if the line starts with 'Inventory ID'; do

print "\"" r, $2, $3 "\""   # print out a double-quote, the record, OFS, $2, OFS, 
                            # $3 and lastly a double quote
使用
-n
标志禁用默认打印。当一行以“客户ID”开头时,复制该行以保留空间。当找到以“Inventory ID”开头的行时,将保留空间追加到当前行。使用一些神奇的正则表达式来重新排列不同的字段并修复格式


这里有一种使用awk的方法:

awk -F= '{ sub(/,.*/,"",$2) } /^Customer ID/ { r = $2 OFS $3 } /^Inventory ID/ { print "\"" r, $2, $3 "\"" }' OFS="\", \"" inventory.txt
sed
解决方案:

#!/usr/bin/perl
use warnings;
use strict;
use feature qw(say);

my ($customer, $name);
while (<>) {
    if (/Customer ID=(.*), Customer Name=(.*)/) {
        ($customer, $name) = ($1, $2);
    } elsif (/Inventory ID=(.*), Inventory Name=(.*)/) {
        say join ', ' => map qq("$_"), $customer, $name, $1, $2;
    }
}
sed -n '/^Customer ID/ h; /^Inventory ID/ { G; s/.*=\([^,]*\).*=\([^\n]*\).*=\([^,]*\).*=\(.*\)/"\3", "\4", "\1", "\2"/; p }' inventory.txt
结果:

"9000", "Acme, Inc", "INV_ID1", "Acme_INV1"
"9000", "Acme, Inc", "INV_ID2", "Acme_INV2"
"7500", "Anvil, Corp", "INV_ID3", "Anvil_INV1"

awk
说明:

 OFS="\", \""          # set the output field separator to: ", "

-F=                    # split the line into three fields using the '=' character

{ sub(/,.*/,"",$2) }   # one each line of input, remove everything trailing a
                       # comma from field two.

/^Customer ID/ { ... } # if the line starts with 'Customer ID'; do

r = $2 OFS $3          # build a record using field two and three separated by 'OFS'

/^Inventory ID/ {...}  # if the line starts with 'Inventory ID'; do

print "\"" r, $2, $3 "\""   # print out a double-quote, the record, OFS, $2, OFS, 
                            # $3 and lastly a double quote
sed
说明:

 OFS="\", \""          # set the output field separator to: ", "

-F=                    # split the line into three fields using the '=' character

{ sub(/,.*/,"",$2) }   # one each line of input, remove everything trailing a
                       # comma from field two.

/^Customer ID/ { ... } # if the line starts with 'Customer ID'; do

r = $2 OFS $3          # build a record using field two and three separated by 'OFS'

/^Inventory ID/ {...}  # if the line starts with 'Inventory ID'; do

print "\"" r, $2, $3 "\""   # print out a double-quote, the record, OFS, $2, OFS, 
                            # $3 and lastly a double quote
使用
-n
标志禁用默认打印。当一行以“客户ID”开头时,复制该行以保留空间。当找到以“Inventory ID”开头的行时,将保留空间追加到当前行。使用一些神奇的正则表达式来重新排列不同的字段并修复格式


另一个awk一个班轮,不使用FS

awk -vq="\"" '/^(Cus|Inv)/{f=$0~/^Cus/;gsub(/[^,]*=/,q);sub(/,/,q",");c=f?$0q:c;if(!f)print c","$0q}' file
测试:


另一个awk一个班轮,不使用FS

awk -vq="\"" '/^(Cus|Inv)/{f=$0~/^Cus/;gsub(/[^,]*=/,q);sub(/,/,q",");c=f?$0q:c;if(!f)print c","$0q}' file
测试:

这可能适用于您(GNU-sed):

这可能适用于您(GNU-sed):


对函数使用gawk扩展

输出

"9000","Acme, Inc","INV_ID1","Acme_INV1"
"9000","Acme, Inc","INV_ID2","Acme_INV2"
"7500","Anvil, Corp","INV_ID3","Anvil_INV1"

对函数使用gawk扩展

输出

"9000","Acme, Inc","INV_ID1","Acme_INV1"
"9000","Acme, Inc","INV_ID2","Acme_INV2"
"7500","Anvil, Corp","INV_ID3","Anvil_INV1"

你应该考虑客户姓名有逗号。该死,你又揍了我一顿。1.你能评论一下你的代码在做什么吗?我对BASH脚本比较陌生。提前谢谢!当然,我会在一分钟内添加关于
awk
解决方案的解释。但正如您所看到的,我添加了一个
sed
解决方案。我只是想看看是否可以先减少正则表达式,使其更具可读性。我认为这是可以做到的。这太棒了!!非常感谢您提供这两种解决方案。我正在根据自己的需要配置SED解决方案。非常感谢您的帮助!!:)你应该考虑客户姓名有逗号。该死,你又揍了我一顿。1.你能评论一下你的代码在做什么吗?我对BASH脚本比较陌生。提前谢谢!当然,我会在一分钟内添加关于
awk
解决方案的解释。但正如您所看到的,我添加了一个
sed
解决方案。我只是想看看是否可以先减少正则表达式,使其更具可读性。我认为这是可以做到的。这太棒了!!非常感谢您提供这两种解决方案。我正在根据自己的需要配置SED解决方案。非常感谢您的帮助!!:)这在sed中很棘手,可能是不可能的。我一直在尝试设想一种方法,使用sed的“保留空间”保留客户ID和姓名的副本,然后针对每个库存行,将相关数据附加到保留空间并打印,但似乎任何对保留空间的使用都会修改它,从而使特定客户的第二个(或更多)库存行的保留空间无效。虽然在
sed
中努力寻找实现这一点的方法既有趣又有教育意义,但如果你只是想完成这项工作,steve的awk one liner看起来会奏效。这在sed中很棘手,而且可能是不可能的。我一直在尝试设想一种方法,使用sed的“保留空间”保留客户ID和姓名的副本,然后针对每个库存行,将相关数据附加到保留空间并打印,但似乎任何对保留空间的使用都会修改它,从而使特定客户的第二个(或更多)库存行的保留空间无效。虽然在
sed
中努力寻找实现这一点的方法既有趣又有教育意义,但如果你只是想完成这项工作,steve的awk one liner看起来会奏效。