1

次のようなレコードでいっぱいのファイルが1つあります。

"Full name","URL-style name","key_1a","key_2a"
"Full name","URL-style name","key_1b","key_2b"
"Full name","URL-style name","key_1c","key_2c"
...

次のようなレコードでいっぱいの別のファイルがあります。

"URL-style name","key_1a","key_2a"
"URL-style name","key_1b","key_2b"
"URL-style name","key_1c","key_2c"
...

()が主キー(一意)であることを知っているので、2番目のファイルに列"key_1","key_2"を追加したいと思います。"Full name"

これをどのように行いますか?vimで、またはで解決策を探していbash shell scriptます。

4

4 に答える 4

3

サンプルデータの修正バージョンを見てみましょう。

file1

"Full nameA","URL-style name","key_1a","key_2a"
"Full nameB","URL-style name","key_1b","key_2b"
"Full nameC","URL-style name","key_1c","key_2c"

file2

"URL-style name1","key_1a","key_2a"
"URL-style name2","key_1b","key_2b"
"URL-style name3","key_1c","key_2c"

処理

コメントに記載されているように、コマンドの1つの制限は、1つのjoin列でしか結合できないことですが、質問には2つの列を持つ複合キーがあります。もちろん、これを回避する方法はいくつかあります。基本的にjoin、複合列が使用される区切り文字の下で単一の列として識別できるように入力を再フォーマットし、各ファイルのデータがその順序で正しくソートされていることを確認する必要があります複合カラム。それにもかかわらず、joinおそらくそれを行う方法です。必要な準備作業と後処理がいくつかあります。また、Bash v4には、このコマンドに非常に役立つ「プロセス置換」があります。

  1. file1必要なデータを使用して、から結合可能なファイルを生成します。

    これを行うにはいくつかの方法があります。両方sed(やや不可解に)またはawk使用できます:

    $ sed 's/\([^,]*\),[^,]*,\([^,]*\),\([^,]*\)/\2:\3,\1/' file1
    "key_1a":"key_2a","Full nameA"
    "key_1b":"key_2b","Full nameB"
    "key_1c":"key_2c","Full nameC"
    $ awk -F, '{ printf "%s:%s,%s\n", $3, $4, $1 }' file1
    "key_1a":"key_2a","Full nameA"
    "key_1b":"key_2b","Full nameB"
    "key_1c":"key_2c","Full nameC"
    $
    
  2. file2必要なデータを使用して、結合可能なファイルを生成します。

    $ sed 's/\([^,]*\),\([^,]*\),\([^,]*\)/\2:\3,\1/' file2
    "key_1a":"key_2a","URL-style name1"
    "key_1b":"key_2b","URL-style name2"
    "key_1c":"key_2c","URL-style name3"
    $ awk -F, '{ printf "%s:%s,%s\n", $2, $3, $1 }' file2
    "key_1a":"key_2a","URL-style name1"
    "key_1b":"key_2b","URL-style name2"
    "key_1c":"key_2c","URL-style name3"
    $ 
    
  3. この前処理を考えるとsort、データを準備するのにストレートで十分ですjoin

    $ join -t, -o 2.2,0,1.2 \
    >      <(awk -F, '{ printf "%s:%s,%s\n", $3, $4, $1 }' file1 | sort) \
    >      <(awk -F, '{ printf "%s:%s,%s\n", $2, $3, $1 }' file2 | sort)
    "URL-style name1","key_1a":"key_2a","Full nameA"
    "URL-style name2","key_1b":"key_2b","Full nameB"
    "URL-style name3","key_1c":"key_2c","Full nameC"
    $ 
    
  4. 次に、コロンをコンマに後処理する必要があります。

    $ join -t, -o 2.2,0,1.2 \
    >      <(awk -F, '{ printf "%s:%s,%s\n", $3, $4, $1 }' file1 | sort) \
    >      <(awk -F, '{ printf "%s:%s,%s\n", $2, $3, $1 }' file2 | sort) |
    > sed 's/":"/","/'
    "URL-style name1","key_1a","key_2a","Full nameA"
    "URL-style name2","key_1b","key_2b","Full nameB"
    "URL-style name3","key_1c","key_2c","Full nameC"
    $ 
    

明らかに、コロンの代わりに適切な文字を選択できます。Control-A(0x01)がHTMLに表示される可能性はほとんどありません。

これは、示されているように、CSVデータの文字列にコンマが含まれていないことを前提としています。文字列内にコンマがある場合、人生ははるかに困難です。データを処理するには、適切なCSVインタープリターが必要です。PerlにはText::CSVあり、ありcsvfixます。

于 2013-03-09T16:52:40.590 に答える
1

awk

$ awk -F, 'NR==FNR{a[$3$4]=$1;next}($2$3 in a){print a[$2$3]","$0}' file1 file2
"Full name","URL-style name","key_1a","key_2a"
"Full name","URL-style name","key_1b","key_2b"
"Full name","URL-style name","key_1c","key_2c"
于 2013-03-09T16:57:07.560 に答える
0

検索しているコマンドはですjoin

詳細はこちらをご覧くださいman join

コマンドをpfull.txt:6: is not sorted使用して前に入力ファイルを並べ替えるか、オプションを試してみるなどのエラーが発生した場合。sort--nocheck-order

于 2013-03-09T15:34:57.970 に答える
0

データは両方のファイルで同じ順序であるため、エントリを互いに一致させる必要がない場合は、次のようにします。

VimVISUALBLOCKモードを使用します。

2つのウィンドウでVimの両方のファイルを開き(:sp <filename>またはそれ:vsp <filename>を支援します)、で目的のテキストのブロック選択を開始しCTRLv、でコピーしyます。

CTRLwh j k l垂直分割か水平分割かによって、ウィンドウ間を移動します。

クリップボードのデータを貼り付ける場所にカーソルを置き、を押しpます。

于 2013-03-09T18:20:04.277 に答える