5

次の形式の2つのテキストファイルがあります。

1つ目は、すべての行でこれです。

Key1:Value1

2番目はこれです:

Key2:Value2

キーインとして使用して得られたValue1ものに置き換える方法はありますか?file1Value2file2

例えば:

file1:

foo:hello
bar:world

file2:

hello:adam
bar:eve

取得したい:

foo:adam
bar:eve

すべての行で2つのファイルが一致するとは限りません。これはawkか何かできれいに行うことができますか、それともPythonで素朴に行う必要がありますか?

4

7 に答える 7

3

ファイルごとに1つずつ、合計2つの辞書を作成します。例えば:

file1 = {}
for line in open('file1', 'r'):
    k, v = line.strip().split(':')
    file1[k] = v

または、ワンライナーを好む場合:

file1 = dict(l.strip().split(':') for l in open('file1', 'r'))

次に、次のようなことを行うことができます。

result = {}
for key, value in file1.iteritems():
    if value in file2:
        result[key] = file2[value]

もう1つの方法は、file1とuseセットのキーと値のペアを逆に生成することです。たとえば、file1にが含まれている場合、foo:barfile1dictはです{bar: foo}

for key in set(file1) & set(file2):
    result[file1[key]] = file2[key]

基本的に、setintersectionを使用して共通の要素をすばやく見つけることができるため、それらの要素はfile2にあることが保証され、それらの存在を確認する時間を無駄にすることはありません。

編集: @peprが指摘したようcollections.OrderedDictに、順序が重要な場合は、最初の方法に使用できます。

于 2012-05-05T08:26:14.787 に答える
2

awkソリューション:

awk '
  BEGIN {FS = OFS = ":"}
  NR==FNR {val[$1] = $2; next}
  $1 in val {$2 = val[$1]}
  {print}
}' file2 file1
于 2012-05-05T11:56:43.887 に答える
1
join -t : -1 2 -2 1 -o 0 2.2 -a 2 <(sort -k 2 -t : file1) <(sort file2)

入力ファイルは、結合されているフィールドでソートする必要があります。

オプション:

  • -t :-区切り文字としてコロンを使用します
  • -1 2-ファイル1のフィールド2に参加します
  • -2 1-ファイル2のフィールド1に参加します
  • -o 0 2.2-結合フィールドの後にフィールド2をfile2から出力します(区切り文字で区切ります)。
  • -a 2-ファイル2から結合されていない行を出力します
于 2012-05-05T11:06:15.257 に答える
0

あなたが持ったら:

file1 = {'foo':'hello', 'bar':'world'}
file2 = {'hello':'adam', 'bar':'eve'}

あなたは醜いワンライナーを行うことができます:

print dict([(i,file2[i]) if i in file2 else (i,file2[j]) if j in file2 else (i,j) for i,j in file1.items()])
{'foo': 'adam', 'bar': 'eve'}

あなたの例のように、あなたはkeysvaluesの両方file1を使用keysしていfile2ます。

于 2012-05-05T09:19:12.780 に答える
0

基本的なUnix/Linuxコマンドの不正使用を検討していない場合は、pasteとawkを使用した解決策があります。

paste file1.txt file2.txt | awk -F ":" '{ print $1":"$3 }'

于 2012-05-05T10:14:25.020 に答える
0

これはあなたのために働くかもしれません(おそらくGNU sed):

sed 's#\([^:]*\):\(.*\)#/\\(^\1:\\|:\1$\\)/s/:.*/:\2/#' file2 | sed -f - file1
于 2012-05-05T14:17:26.707 に答える
0

TXR:

@(next "file2")
@(collect)
@key:@value1
@  (cases)
@    (next "file1")
@    (skip)
@value2:@key
@  (or)
@    (bind value2 key)
@  (end)
@  (output)
@value2:@value1
@  (end)
@(end)

走る:

$ txr subst.txr
foo:adam
bar:eve
于 2012-05-07T05:09:17.533 に答える