1

私は2つのファイルを持っています:

file1.txt

919167,hutch,mumbai
919594,idea,mumbai

file2.txt

919167000000
919594000000 

出力

919167000000,hutch,mumbai
919594000000,idea,mumbai

AWK を使用してこれを達成するにはどうすればよいですか? このように比較する必要がある電話番号の膨大なファイルがあります。私は Awk がそれを処理できると信じています。そうでない場合は、どうすればよいか教えてください。


追加の定義

  • 共通部分は常に6桁の数字ですか?はい、常に 6。
  • 2 つのファイルは既にソートされていますか? file1 はソートされていません。file2 はソートできます。
  • ファイル 2 の末尾の数字は常にゼロですか? いいえ、これらは異なる電話番号です。これの目的は、電話番号のシリーズ情報を取得することです。
  • ファイル 1 には特定の番号の 3 つのレコードが含まれ、ファイル 2 には 2 つのレコードが含まれているという危険性はありますか、それとも 1 対 1 ですか? 一対一です。ファイル 1 にレコードが存在し、ファイル 2 に一致しないレコードが存在する可能性はありますか?_ はい。
  • その場合、一致しないレコードを表示しますか? はい、両方のレコードが必要です。

拡張データ

file1.txt

919167,hutch,mumbai
919594,idea,mumbai
918888,airtel,karnataka

file2.txt

919167838888
919594998484
919212334323

期待される出力:

919167838888,hutch,mumbai
919594998484,idea,mumbai
919212334323,nomatch,nomatch
4

3 に答える 3

2

を使用する1つの方法がありGNU awkます。次のように実行します:

awk -f script.awk file2.txt file1.txt

内容script.awk

BEGIN {
    FS=OFS=","
}

FNR==NR {
    sub(/[ \t]+$/, "")
    line = substr($0, 0, 6)
    array[line]=$0
    next
}

{
    printf ($1 in array) ? $0"\n" : "FILE1 no match --> "$0"\n"
    dup[$1]++
}

END {
    for (i in array) {
        if (!(i in dup)) {
            printf "FILE2 no match --> %s\n", array[i]
        }
    }
}

または、これがワンライナーです。

awk 'BEGIN { FS=OFS="," } FNR==NR { sub(/[ \t]+$/, ""); line = substr($0, 0, 6); array[line]=$0; next } { printf ($1 in array) ? $0"\n" : "FILE1 no match --> "$0"\n"; dup[$1]++} END { for (i in array) if (!(i in dup)) printf "FILE2 no match --> %s\n", array[i] }' file2.txt file1.txt
于 2012-10-04T05:55:12.173 に答える
2

コメントで指摘したように、決定的な回答を得るには、多くの記載されていない情報が必要です。ただし、いくつかのもっともらしい推測を行うことができます。

  1. 共通の番号は、ファイル 2 の最初の 6 桁です (末尾の数字は気にしませんが、単純に出力にコピーします)。
  2. ファイルは順番にソートされます。
  3. いずれかのファイルに一致しないレコードがある場合、それらのレコードは無視されます。

最適なツールは、おそらく次sedjoinとおりです。

sed 's/^\([0-9]\{6\}\)/\1,\1/' file2.txt |
join -t, -o 1.2,2.2,2.3 - file1.txt

これを編集file2.txtして、6 桁の電話番号とそれに続くすべての行のコンマ区切りの最初のフィールドを作成します。入力はjoinコマンドに供給され、最初の列で結合され、 から「行の残り」(列 2)file2.txtと から列 2 および 3 が出力されfile1.txtます。

電話番号が可変長の場合、照合操作は非常に複雑です。そのためには、Perl (または Python) を使って作業を行います。データがソートされていない場合は、コマンドに入力する前にソートできます。不一致のレコードが必要な場合は、オプションでそれらの処理方法を に指定できますjoin


必要な追加情報が利用可能になりました。重要な情報は 6 桁が固定されていることです。あなたはLinuxを使用しているのでbash、「プロセス置換」で利用できると思います:

sort file2.txt |
sed 's/^\([0-9]\{6\}\)/\1,\1/' |
join -t, -o 1.2,2.2,2.3 -a 1 -a 2 -e 'no-match' - <(sort file1.txt)

file1.txtプロセスの代替が利用できない場合は、その場でソートするだけです。

sort -o file1.txt file1.txt

次にfile1.txt、の代わりに使用し<(sort file1.txt)ます。


コメントは、次のような入力を求めている可能性があると思います。

file1.txt

919167,hutch,mumbai
919594,idea,mumbai
902130,airtel,karnataka

file2.txt

919167000000
919594000000
919342313242

出力

no-match,airtel,karnataka
919167000000,hutch,mumbai
919342313242,no-match,no-match
919594000000,idea,mumbai

それがコメントの内容ではない場合は、質問を編集して余分なデータを追加し、コメントよりも読みやすい形式で出力して明確にしてください。


拡張データを使用して、この少し変更されたコマンド:

sort file2.txt |
sed 's/^\([0-9]\{6\}\)/\1,\1/' |
join -t, -o 1.2,2.2,2.3 -a 1 -e 'no-match' - <(sort file1.txt)

出力を生成します:

919167838888,hutch,mumbai
919212334323,no-match,no-match
919594998484,idea,mumbai

これは、目的の出力のソートされたバージョンのように見えます。オプションは、ファイル 1 またはファイル 2 (または両方)の-a n一致しないレコードを印刷するかどうかを制御します。この-eオプションは、一致しないフィールドに対して出力される値を制御します。joinもちろん、これらはすべて の man ページから簡単に入手できます。

于 2012-10-04T05:50:42.050 に答える
0
awk -F, 'FNR==NR{a[$1]=$2","$3;next}{for(i in a){if($1~/i/) print $1","a[i]}}' your_file
于 2012-10-04T09:16:56.503 に答える