1

このような表形式のファイルで列を交換する簡単な方法はありますか?

キーは 1 列目と 3 列目ですが、2 列目を最初のキーに追加し、4 列目を 3 列目に追加する必要があります。列間のスワップは、2 番目のキー (3 列目) に対する最初のキー (1 列目) の存在に依存します。

A B C D    
E F A B
H I A G
J K L M 
N J Q K

望ましい出力は次のようになります。

A B C D    
A B E F
A G H I 
J K L M 
N J Q K
4

2 に答える 2

1

Perl を使用した簡単なソリューションを次に示します。これは、同じ行の 2 つの奇数列が同じ内容の場合に失敗します。たとえば、

C D C A # Would print out "C A" only

それ以外の場合は、キーと値のペアを簡単に操作できるハッシュ データ構造を使用できます。

perl -ple'%h=split;$_=join" ",map{$_=>$h{$_}}sort keys %h'

使用例:

$ perl -ple'%h=split;$_=join" ",map{$_=>$h{$_}}sort keys %h' <<'END'
A B C D    
E F A B
H I A G
J K L M 
N J Q K
END

出力:

A B C D
A B E F
A G H I
J K L M
N J Q K

その弱点がなければ、私はそれを次のように書きます

perl -pale'@f=();push@f,[splice@F,0,2]while@F;$_=join" ",map@$_,sort{$a->[0]cmp$b->[0]}@f'

これは本質的にシュワルツ変換を行います。

説明

最初の解決策:

このオプション-lは、行末を処理します。-pすべての入力行をループし (それらを に入れます)、反復ごと$_に の内容を出力します。$_

ハッシュは、交互のキーと値のリストとして構築されます。オプションのsplitない関数は、空白の内容を分割$_し、 hash に割り当てるリストを返します%h。重複したキーは削除されます。最後のオカレンスのみが設定されます。

アルファベット順ですsort。は各キーを取得し、キーのリストを交互のキーと値のリストに変換しますが、今回は正しい順序で変換します。keysmap

join単一のスペースを介してこの文字列のリストを に割り当て$_ます-p

2番目の解決策:

-aオプション autoは配列split$_挿入されます。with@Fの最初の 2 つの要素を取り、それらを匿名の arrayref に入れ、この arrayref を配列にプッシュします。要素がなくなるまで繰り返します。これにより、 の内容がペアになり、重複に悩まされることはありません。@Fsplice@f@F

最初の要素をアルファベット順に配列参照し、結果の順序を で平坦化しsortます。その後、前と同じように文字列を結合します。@fmap

于 2013-02-05T21:26:46.163 に答える
1

これはうまくいきます。「ワンライナー」で作成することもできますが、この方法で貼り付けた方が読みやすいと思います。

awk 'NR==1{a[$1];print;next;}!($1 in a){
r="";h=$1;
for(i=2;i<=NF;i++)
    if($i in a){
        for(m=i;m<=NF;m++)
            r=(r?r" ":"")$m
            break;
        }else{
        h=h" "$i
    }
    $0=(r?r" ":"")h;
}1' file

あなたのデータでテストしてください:

kent$ echo "A B C D    
E F A B
H I A G
J K L M 
N J Q K"|awk 'NR==1{a[$1];print;next;}!($1 in a){
r="";h=$1;
for(i=2;i<=NF;i++)
        if($i in a){
                for(m=i;m<=NF;m++)
                        r=(r?r" ":"")$m
                        break;
                }else{
                h=h" "$i
        }
        $0=(r?r" ":"")h;
}1'
A B C D    
A B E F
A G H I
J K L M
N J Q K
于 2013-02-05T20:45:18.110 に答える