0

さて、私はせいぜいbashスクリプトの初心者ですが、昨夜遅くにこの非常に小さなスクリプトを作成して、かなり大きなテキストファイル(〜300,000行)の各行の最初の40文字を取得し、はるかに大きなテキストファイルを検索して一致 (約 220 万行) し、一致する行のすべての結果を新しいテキスト ファイルに出力します。

スクリプトは次のようになります。

#!/bin/bash
while read -r line
  do
  match=${line:0:40}
  grep "$match" large_list.txt
done <"small_list.txt"

そして、そのようにスクリプトを呼び出すことによって

$ bash my_script.sh > outputfile.txt &

これにより、2 つのリストに共通するすべての要素が得られます。今、これはすべて順調で、ゆっくりと機能しています。しかし、私はこれを m1.smalll ec2 インスタンスで実行しており、十分に公平です (これでの処理はたわごとであり、より大きなインスタンスを起動してこれらすべてを処理するか、デスクトップで実行してファイルをアップロードすることができます)。ただし、同じタスクを達成するためのより効率的な方法を学びたいのですが、これを理解することはできません。これについて最善を尽くす方法、またはより効率的にタスクを完了する方法についてのちょっとした情報は、本当に非常に高く評価されます

これがどれだけ遅いかお分かりいただけると思いますが、私は約 10 時間前にスクリプトを開始し、すべての試合の約 10% を完了しました。

また、私はbashの使用に慣れていないため、他の言語のスクリプトは公正なゲームです..私は、プロがSOを使用していると、ハンマーアプローチのロックを簡単に改善できると考えています

編集: 入力と出力の追加、およびデータに関する詳細情報の追加

 input: (small text file)
  8E636C0B21E42A3FC6AA3C412B31E3C61D8DD062|Vice S01E09 HDTV XviD-FUM[ettv]|Video TV|http://bitsnoop.com/vice-s01e09-hdtv-xvid-fum-ettv-q49614889.html|http://torrage.com/torrent/36A02E282D49EB7D94ACB798654829493CA929CB.torrent
  3B9403AD73124A84AAE12E83A2DE446149516AC3|Sons of Guns S04E08 HDTV XviD-FUM[ettv]|Video TV|http://bitsnoop.com/sons-of-guns-s04e08-hdtv-xvid-fum-e-q49613491.html|http://torrage.com/torrent/3B9403AD73124A84AAE12E83A2DE446149516AC3.torrent
  C4ADF747050D1CF64E9A626CA2563A0B8BD856E7|Save Me S01E06 HDTV XviD-FUM[ettv]|Video TV|http://bitsnoop.com/save-me-s01e06-hdtv-xvid-fum-ettv-q49515711.html|http://torrage.com/torrent/C4ADF747050D1CF64E9A626CA2563A0B8BD856E7.torrent
  B71EFF95502E086F4235882F748FB5F2131F11CE|Da Vincis Demons S01E08 HDTV x264-EVOLVE|Video TV|http://bitsnoop.com/da-vincis-demons-s01e08-hdtv-x264-e-q49515709.html|http://torrage.com/torrent/B71EFF95502E086F4235882F748FB5F2131F11CE.torrent

 match against (large text file)

  86931940E7F7F9C1A9774EA2EA41AE59412F223B|0|0
  8E636C0B21E42A3FC6AA3C412B31E3C61D8DD062|4|2|20705|9550|21419
  ADFA5DD6F0923AE641F97A96D50D6736F81951B1|0|0
  CF2349B5FC486E7E8F48591EC3D5F1B47B4E7567|1|0|429|428|22248
  290DF9A8B6EC65EEE4EC4D2B029ACAEF46D40C1F|1|0|523|446|14276
  C92DEBB9B290F0BB0AA291114C98D3FF310CF0C3|0|0|21448


 Output: 
  8E636C0B21E42A3FC6AA3C412B31E3C61D8DD062|4|2|20705|9550|21419

追加の説明: 基本的に、入力ファイルの最初の 40 文字のハッシュがあります (ファイルのサイズは既に元のサイズの約 15% に縮小されているため、このファイルの各行に対して、より大きなテキスト ファイルにハッシュがあります (対応する情報を使用して、新しいファイルに書き込みたいのは大きなファイルの行であるため、最終的に小さなテキスト ファイルのすべてのものと私のテキスト ファイルの比率は 1:1 になります。 output_file.txt この場合、入力の最初の行 (より大きなファイルの 2 行目) が一致し、出力ファイルに書き込まれることを示しています。

4

2 に答える 2

2

awkこの回答から採用されたソリューション:

awk -F"|" 'NR==FNR{a[$1]=$2;next}{if (a[$1]) print}' small.txt large.txt
于 2013-06-11T20:08:52.240 に答える
1

救助のためのいくつかのpython。

次のスニペットを使用して 2 つのテキスト ファイルを作成しました。

#!/usr/bin/env python

import random
import string

N=2000000
for i in range(N):
    s = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(40))
    print s + '|4|2|20705|9550|21419'

1 つの 300k 行と 1 つの 2M 行これにより、次のファイルが得られます。

$ ll
-rwxr-xr-x 1  210 Jun 11 22:29 gen_random_string.py*
-rw-rw-r-- 1 119M Jun 11 22:31 large.txt
-rw-rw-r-- 1  18M Jun 11 22:29 small.txt

次に、small.txt から large.txt の末尾に行を追加して、一致するパターンを作成しました。

次に、さらに python:

#!/usr/bin/env python

target = {}

with open("large.txt") as fd:
    for line in fd:
        target[line.split('|')[0]] = line.strip()

with open("small.txt") as fd:
    for line in fd:
        if line.split('|')[0] in target:
            print target[line.split('|')[0]]

いくつかのタイミング:

$ time ./comp.py 
3A8DW2UUJO3FYTE8C5ESE25IC9GWAEJLJS2N9CBL|4|2|20705|9550|21419

real    0m2.574s
user    0m2.400s
sys 0m0.168s

$ time awk -F"|" 'NR==FNR{a[$1]=$2;next}{if (a[$1]) print}' small.txt large.txt
3A8DW2UUJO3FYTE8C5ESE25IC9GWAEJLJS2N9CBL|4|2|20705|9550|21419

real    0m4.380s
user    0m4.248s
sys 0m0.124s

アップデート:

メモリを節約するには、辞書検索を別の方法で行います

#!/usr/bin/env python

target = {}

with open("small.txt") as fd:
    for line in fd:
        target[line.split('|')[0]] = line.strip()

with open("large.txt") as fd:
    for line in fd:
        if line.split('|')[0] in target:
            print line.strip()
于 2013-06-11T20:22:38.667 に答える