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

추신.

첫째, 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로 증가됩니다.

산출:

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

관련 정보