2

下面是我的文件内容,下面是我的要求基于第 1 列和第 5 列中的值,我想用“1”替换第 7 列中的值。

例如:

  1. 如果第 1 列 =“更改”且第 5 列 =“延迟”,则将第 7 列中的值替换为“1”。
  2. 如果第 1 列 =“更改”且第 5 列 =“延迟”,则将第 7 列中的值替换为“1”。
  3. 否则不要对行做任何事情,保持原样。

输入文件:

Change|sinmg|1234|ewfew|def|fdfd|JAMES|rewr|ROBERT|3|fe
Change|sinmg|2345|ewfew|defer|VENKTRAAAMMAMAMAMMAMA|3|rewr|BEAEY|3|
noChange|sinmg|2323|ewfew|def|VENKTRAAAMMAMAMAMMAMA|3|rewr|BEAEY|3|fe
Change|sinmg|3456|ewfew|defer|VENKTRAAAMMAMAMAMMAMA|3|rewr|BEAEY|3|
Change|sinmg|2345|ewfew|defererence|VENKTRAAAMMAMAMAMMAMA|3|rewr|BEAEY|3|

上面只是一个示例,以便于解释。但是我想从文件中传递第 1 列和第 5 列的值以匹配文件中的值。如果匹配,则仅将第 7 列替换为值“1”,否则不对行执行任何操作,保持原样。

我尝试了几个选项,但无法达到所需的结果。

perl -F'\|' -i -lape  'if ($F[0] eq "change" && $F[4] eq "defer") { s/$F[6]/1/g;}' file_name

上面的命令正在替换文件中所有 3 的值,而不考虑字段。但我只想通过在循环中将不同的值传递给第 1 列和第 4 列来替换基于第 1 列和第 4 列的第 6 列值。

添加更多信息:

正如我上面提到的,上面的例子只是我的问题的最简单形式,让大家理解需求。我有一个名为“listfile”的文件,其中包含用于匹配的第 1 列和第 5 列的值列表。如果源文件中第 1 列和第 5 列中的值与从文件“listfile”传递的值匹配,则解决方案应将第 7 列中的值替换为“1”。否则不要对源文件中的行做任何事情,保持原样。

我尝试在下面做,但无法达到要求。

    #!/usr/bin/ksh
    for line in $(cat dir/listfile)
    do
    VAR1=$(echo $line | nawk -F"|" '{print $1}')
    VAR2=$(echo $line | nawk -F"|" '{print $2}')
    nawk -F"|" 'BEGIN {OFS="|"} {if($1!="'"$VAR1"'" && $5!="'"$VAR2"'") {$8="1"; print $0;}      else {print $0;}}' dir/sourcefile >> dir/sourcefile_REVISED
    done

替换第 7 列后,原始源文件和修改后的源文件之间的记录数应相同。唯一的问题是对于文件列表文件中第 1 列和第 5 列的所有值,我需要将第 7 列值替换为“1”。

谢谢,

4

6 回答 6

1
perl -F'\|' -i -lape '
  BEGIN{ $" = "|" }
  $F[6]=1, $_="@F" if $F[0] eq "Change" && $F[4] =~ /^defer(erence)?$/;
' listfile
于 2013-09-24T20:47:13.843 回答
1

您可以使用它awk来执行此操作。

awk -F'|' 'BEGIN{OFS="|"}{if($1=="Change"&&$5=="defer"){$7=1}{print}}' file

我意识到您还需要第 5 列来匹配“差异”...以下应该可以工作:

awk -F'|' 'BEGIN{OFS="|"}{if($1=="Change"&&$5=="defer"||$5=="defererence"){$7=1}{print}}' file
于 2013-09-24T19:34:47.857 回答
0

替代运算符s///不理解数据列的概念,它只是对给定的字符串进行操作。在这种情况下,您将替换第 7 列中的任何内容,因为g它由于修饰符而出现在输入行中。

awk@imauser 的答案中的解决方案是一个很好的解决方案。

于 2013-09-24T19:40:25.373 回答
0

在进行替换之前,您仍然可以通过“跳过”前六个字段来使用 perl+regexp 解决方案:

perl -F'\|' -i -lapE  'if ($F[0] eq "change" && $F[4] =~ m{^defer(erence)?$}) { s{^(?:[^|]*\|){6}\K([^|]*)}{1} }' file_name

与 awk 解决方案相比的优势:您仍然可以在-i此处使用开关。

于 2013-09-24T20:20:21.700 回答
0

awk你一起做:

$ awk '$1=="Change"&&$5~/^defer(erence)?$/{$7=1}1' FS='|' OFS='|' file
Change|sinmg|1234|ewfew|def|fdfd|JAMES|rewr|ROBERT|3|fe
Change|sinmg|2345|ewfew|defer|VENKTRAAAMMAMAMAMMAMA|1|rewr|BEAEY|3|
noChange|sinmg|2323|ewfew|def|VENKTRAAAMMAMAMAMMAMA|3|rewr|BEAEY|3|fe
Change|sinmg|3456|ewfew|defer|VENKTRAAAMMAMAMAMMAMA|1|rewr|BEAEY|3|
Change|sinmg|2345|ewfew|defererence|VENKTRAAAMMAMAMAMMAMA|1|rewr|BEAEY|
于 2013-09-24T19:42:19.427 回答
0

split您可以使用和join在脚本中实现这一点perl,如下所示:

#!/usr/bin/perl
use warnings;
use strict;

my $infile = "dir/sourcefile";
my $listfile = "dir/listfile";
my $outfile = "dir/sourcefile_REVISED";

my @list;
open LFOPEN, $listfile or die $!;
while (<LFOPEN>) {
    chomp;
    my @col = split /\|/, $_;
    push @list, \@col;
}
close LFOPEN;

open IFOPEN, $infile or die $!;
open OFOPEN, '>', $outfile or die $!;
while (<IFOPEN>) {
    chomp;
    my @col = split /\|/, $_;
    foreach my $lref (@list) {
        $col[6] = '1' if ($col[0] eq $lref->[0] and $col[4] eq $lref->[1]);
    }
    print OFOPEN join ('|', @col) . "\n";
}
close IFOPEN;
close OFOPEN;

输入(目录/源文件):

Change|sinmg|1234|ewfew|def|fdfd|JAMES|rewr|ROBERT|3|fe
Change|sinmg|2345|ewfew|defer|VENKTRAAAMMAMAMAMMAMA|3|rewr|BEAEY|3|
noChange|sinmg|2323|ewfew|def|VENKTRAAAMMAMAMAMMAMA|3|rewr|BEAEY|3|fe
Change|sinmg|3456|ewfew|defer|VENKTRAAAMMAMAMAMMAMA|3|rewr|BEAEY|3|
Change|sinmg|2345|ewfew|defererence|VENKTRAAAMMAMAMAMMAMA|3|rewr|BEAEY|3|

列表(目录/列表文件):

Change|defer
Change|defererence

输出(dir/sourcefile_REVISED):

Change|sinmg|1234|ewfew|def|fdfd|JAMES|rewr|ROBERT|3|fe
Change|sinmg|2345|ewfew|defer|VENKTRAAAMMAMAMAMMAMA|1|rewr|BEAEY|3
noChange|sinmg|2323|ewfew|def|VENKTRAAAMMAMAMAMMAMA|3|rewr|BEAEY|3|fe
Change|sinmg|3456|ewfew|defer|VENKTRAAAMMAMAMAMMAMA|1|rewr|BEAEY|3
Change|sinmg|2345|ewfew|defererence|VENKTRAAAMMAMAMAMMAMA|1|rewr|BEAEY|3
于 2013-09-24T21:41:36.467 回答