AWKを使用して列Aと列Bの値が双方向であることを確認する最も簡単な方法は何ですか? [閉鎖]

AWKを使用して列Aと列Bの値が双方向であることを確認する最も簡単な方法は何ですか? [閉鎖]

A列とB列の値が双方向に進むことを確認する最も簡単な方法は何ですか?

確認する出力:

Mike John
John Mike
Pamela Barbara
Barbara Pamela
Mike Paul
Roger Paul

希望の出力

Mike <-> John
Pamela <-> Barbara
Mike -> Paul
Roger -> Paul

PS。

まず、列Aと列Bのすべての可能な値を調べて、各行の単語数を計算するのと同じです。

Mike John 1 1
Pamela Barbara 1 1
Mike Paul 1 0 
Roger Paul 1 0

その後、変更内容を希望の変更内容に出力します。

答え1

順序が問題にならない場合は、このハッシュソリューションを使用できますawk

BEGIN { d = "|" }
{
  if(names[$2 d $1] > 0)
    ++names[$2 d $1]
  else
    ++names[$1 d $2]
}

END { 
  for(n in names) { 
    split(n, a, d)
    if(names[n] >= 2)
      print a[1] " <-> " a[2]

    if(names[n] == 1)
      print a[1] " -> " a[2]
  }
}

ハッシュ値は、パイプ(変数d)で区切られた2つの名前の接続で初期化されます。これらの名前が逆の順序で再現されると、ハッシュの特定の要素が2に増加します。

出力:

Pamela <-> Barbara
Mike -> Paul
Roger -> Paul
Mike <-> John

答え2

わかりました。今タグ付けしたので、タイトルが次のようになっても

#!/usr/bin/env python

input_file    = 'input.dat'    
out_data      = []
relationships = []

in_fh = open(input_file, 'r')
for line in in_fh:
    x, y = line.split()

    # If the reverse mapping was already seen...
    if (y, x) in out_data:    
        # ... then update the reverse mapping to point both ways
        idx = out_data.index( (y, x) )
        relationships[idx] = '<->'

    # Otherwise, we have no reverse mapping yet...
    else:
        # if we haven't seen the forward mapping yet either...
        if (x, y) not in out_data:    
            # ...then record the forward mapping
            out_data.append( (x, y) )
            relationships.append('->')

in_fh.close()    

# Print the final mappings
for (x, y), arrow in zip(out_data, relationships):
    print "%s %s %s" % (x, arrow, y)

答え3

これは私のものです。失敗bashスクリプトは配列やハッシュの使用を避けようとします。 (bothways.txtファイルにはサンプルデータが含まれています)。

#!/bin/bash

sourcefile=bothways.txt
reversefile=bothways2.txt
dupefile=bothways3.txt

# Create reverse file by swapping the columns
sed -r 's/(\w+)(\s+)(\w+)/\3\2\1/g' <$sourcefile >$reversefile

# Create dupe file by concatenating source and reverse files
# and displaying the duplicate lines
cat $sourcefile $reversefile | sort | uniq -d >$dupefile

while read line
do
    if grep "$line" $dupefile >/dev/null
    then
        arrow='<->';
    else 
        arrow='->';
    fi
    echo $line | sed -r "s/(\w+)\s+(\w+)/\1 $arrow \2/g"
done < $sourcefile

出力:

Mike <-> John
John <-> Mike
Pamela <-> Barbara
Barbara <-> Pamela
Mike -> Paul
Roger -> Paul

出力の問題は、重複した行が含まれていることです。 (縁は合いますが。)

答え4

ここでbashの同じアルゴリズム

#!/bin/bash

while read n1 n2; do
  n1=${n1//[^[:alpha:]]}
  n2=${n2//[^[:alpha:]]}
  n=___${n2}_$n1
  k=${!n}
  if ((k>0)); then
    ((___${n2}_$n1++))
  else
    ((___${n1}_$n2++))
  fi
done

for n in ${!___*}; do
  k=${!n}
  n=${n:3}
  if ((k>=2)); then
    echo "${n/_/ <-> }"
  elif ((k==1)); then
    echo "${n/_/ -> }"
  fi
done

関連情報