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
わかりました。今タグ付けしたのでPython、タイトルが次のようになっても
#!/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