2

以下は私のファイルの内容であり、以下は私の要件です列番号1と列番号5の値に基づいて、列7の値を「1」に置き換えたいと思います。

例えば:

  1. 列 1 が「変更」、列 5 が「延期」の場合、列 7 の値を「1」に置き換えます。
  2. 列 1="change" および列 5="defererence" の場合、列 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列目の値のみを置き換えたいです。

詳細情報の追加:

上記で私が述べたように、上記の例は、誰もが要件を理解できるようにするための私の問題の最も単純な形式です。一致する列1と列5の値のリストを持っている「listfile」という名前のファイルがあります。ソースファイルの列 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 番目の列を置き換えた後の改訂されたソース ファイルの間のレコード数は同じである必要があります。唯一のことは、ファイル listfile の列 1 と 5 のすべての値です。列 7 の値を「1」に置き換える必要があります。

ありがとう、

4

6 に答える 6

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

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

これは、次のようにスクリプトでsplitandを使用して実現できます。joinperl

#!/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 に答える
0

置換を行う前に最初の 6 つのフィールドを「スキップ」することで、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

置換演算子s///は、データの列の概念を理解していません。指定された文字列を操作するだけです。この場合、修飾子のために、入力行で発生するすべての列 7 にあるものを置き換えます。g

awk@imauserによる回答の解決策は良い解決策です。

于 2013-09-24T19:40:25.373 に答える