perl -F, -lane '
exists $h{$F[0]} or $h[$h{$F[0]}=@h]=$_;
$h=$_; /,false$/ or $_=$h for $h[$h{$F[0]}];
END{ print for @h; }
' duplicates.file
データ構造:
%h
キーが最初のフィールド(AAA、BBB、CCCなど)であるハッシュと対応する値は、キーが検出された順序を示す番号です。したがって、たとえば、キーAAA => 0、キーBBB => 1、キーCCC => 2。
@h
要素が印刷順に含まれる行である配列。したがって、データにtrueとfalseの両方が見つかった場合、false値が配列に入ります。OTW、1つのタイプのデータがある場合、それは存在します。
別の方法は、GNU sedを使用することです。
sed -Ee '
G
/^([^,]*),(false|true)\n(.*\n)?\1,\2(\n|$)/ba
/^([^,]*)(,true)\n(.*\n)?\1,false(\n|$)/ba
/^([^,]*)(,false)\n((.*\n)?)\1,true(\n|$)/{
s//\3\1\2\5/;h;ba
}
s/([^\n]*)\n(.*)$/\2\n\1/;s/^\n*//
h;:a;$!d;g
' duplicates.file
FWIW、上記のGNU sedコードに対応するPOSIXのコードを以下に示します。
sed -e '
G
/^\([^,]*\),\(false\)\n\(.*\n\)\{0,1\}\1,\2$/ba
/^\([^,]*\),\(false\)\n\(.*\n\)\{0,1\}\1,\2\n/ba
/^\([^,]*\),\(true\)\n\(.*\n\)\{0,1\}\1,\2$/ba
/^\([^,]*\),\(true\)\n\(.*\n\)\{0,1\}\1,\2\n/ba
/^\([^,]*\),true\n\(.*\n\)\{0,1\}\1,false$/ba
/^\([^,]*\),true\n\(.*\n\)\{0,1\}\1,false\n/ba
/^\([^,]*\)\(,false\)\n\(\(.*\n\)\{0,1\}\)\1,true$/{
s//\3\1\2/
h
ba
}
/^\([^,]*\)\(,false\)\n\(\(.*\n\)\{0,1\}\)\1,true\n/{
s//\3\1\2\n/
h
ba
}
y/\n_/_\n/
s/\([^_]*\)_\(.*\)$/\2_\1/;s/^_*//
y/\n_/_\n/
h;:a;$!d;g
' duplicates.file
説明
- このメソッドでは、最終的に印刷される結果をホールドスペースに格納します。
- すべての行を読み取るたびに、現在の行を検査するために、保留スペースの既存の状態に対して、保留スペースをパターンスペースに追加します。
- この比較中に、5つのことが発生する可能性があります。
- a)現在の行は保留行のどこかに一致し、false:false。
- [アクション]同じ偽の状態が見つかったので、何もしない。
- b)現在の行が保留行のどこかに一致し、true:true。
- [アクション]同じ真の状態が見つかったので、何もしません。
- c)現在の行が保留行のどこかに一致し、true:false。
- [アクション]誤った状態がすでに存在するため、何もしない。
- d)現在の行が保留行のどこかに一致していて、false:true。
- [アクション]これには、trueが配置されているのとまったく同じ位置でfalseの行を置き換える必要があるという点で、いくつかの作業が含まれます。
- e)現在の行は保留行のどこにも一致しません。
結果
AA,false
BB,false
CC,false
DD,true
true
、最初の列の最初のインスタンスである場合のみ保持しますか?