2

以下に示すように、10 列のデータのリストがあります。数千行あります。

$1  $2    $3    $4   $5     $6      $7    $8    $9  $10

|  8455 105@O13  |  8132  101@H13  8131  101@O13 |  68.43
|  7490 93@O16   |  8868  110@H16  8867  110@O16 |  68.30
|  7561 94@O12   |  9185  114@H13  9184  114@O13 |  66.83
|  8776 109@O12  |  7481  93@H12   7480  93@O12  |  65.55
|  8867 110@O16  |  8432  105@H23  8431  105@O23 |  64.48
|  9832 122@O13  |  6357  79@H16   6356  79@O16  |  64.44
|  9194 114@O15  |  5699  71@H12   5698  71@O12  |  64.06
|  8849 110@O25  |  5780  72@H12   5779  72@O12  |  63.99

列 $3 と列 $6 から特定の式に一致する行を選択したいと考えています。正規表現として使用したい条件は「@記号の前の数字が両方の列で同じ」です。この条件が一致する場合は、それらの行を新しいファイルに出力します。

私はこのようなものをawkで試しました

awk '$3~/[1@]/  {print $1,$2,$3,$4,$5,$6,$7,$8,$9,$10}' hhHB_inSameLayer_065_128-maltoLyo12per.tbl

しかし、それは私が望むものを与えません。

誰かがこれについて助けてくれれば幸いです。

注: また、perl または python で助けがあれば感謝します。

よろしくお願いします。

4

7 に答える 7

4

awk で次のことを試してください。区切り記号に基づいて配列に分割$3し、それぞれの最初の要素が一致する場合は出力します$6@

awk '{split($3, a, "@"); split($6, b, "@");if (a[1] == b[1]) print}'

またはもっと慣用的に

awk '{split($3, a, "@"); split($6, b, "@")}; a[1] == b[1]' 

または簡単な Python 2.6+ ソリューション

from __future__ import print_function
with open('testfile.txt') as f:
    for line in f:
            fields = line.split()
            fields3 = fields[2].split('@')
            fields6 = fields[5].split('@')
            if fields3[0] == fields6[0]:
                    print(line, end='')
于 2013-07-06T04:28:27.920 に答える
2

GNU のコード:

sed -r '/^\|\s+\S+\s+([0-9]+@).*\|.*\1/!d' file

2 行のヘッダーがあるとします。

sed -r '1,2p;/^\|\s+\S+\s+([0-9]+@).*\|.*\1/!d' file
于 2013-07-06T06:12:48.933 に答える
1

以下は、後方参照を持つ単一の正規表現パターンを使用する Perl のワンライナーです。

perl -ne 'print if m/^\S+\s+\S+\s+(\d+\@)\S+\s+\S+\s+\S+\s+\1/' hhHB_inSameLayer_065_128-maltoLyo12per.tbl > hhHB_inSameLayer_065_128-maltoLyo12per_reduced.tbl

( Vijayの元の問題ステートメントの明らかな欠陥をまだ誰も指摘していないことに驚いています。この例には、指定された基準に一致する記録がありません。)

于 2013-07-07T01:18:26.707 に答える
0

組み込みcsvモジュールを使用する Python ソリューションを次に示します。条件に一致するすべての行がリストに保存されますstored_lines

**ヘッダーをスキップし、複数のスペースを複数の区切り文字として扱わないように編集しました。**

import csv

def is_good(line):
    return line[2][:line[2].find('@')] == line[5][:line[5].find('@')]

# we'll put the lines that match the criteria here.
stored_lines = []

with open('stack.txt') as fr:
    csv_reader = csv.reader(fr, delimiter=' ', skipinitialspace=True)

    # Skip the header
    csv_reader.next()
    csv_reader.next()
    for line in csv_reader:
         if is_good(line): stored_lines.append(line)

print(stored_lines)
于 2013-07-06T04:40:54.563 に答える
0
import re

su = '''
$1  $2    $3    $4   $5     $6      $7    $8    $9  $10

|  8455 105@O13  |  8132  101@H13  8131  101@O13 |  68.43
|  7490 93@O16   |  8868  110@H16  8867  110@O16 |  68.30
|  7561 94@O12   |  9185  94@H13  9184  114@O13 |  66.83
|  8776 109@O12  |  7481  93@H12   7480  93@O12  |  65.55
|  8867 110@O16  |  8432  105@H23  8431  105@O23 |  64.48
|  9832 122@O13  |  6357  79@H16   6356  79@O16  |  64.44
|  9194 114@O15  |  5699  71@H12   5698  71@O12  |  64.06
|  8849 110@O25  |  5780  72@H12   5779  72@O12  |  63.99'''

f = re.compile(
    '(^\|[^|]+?[ \t](\S+?)@\S+[ \t]+?'
    '\|[^|]+?[ \t](\\2)@\S+.+)',
    re.MULTILINE)\
    .finditer

print [m.group(1) for m in f(su)]
于 2013-07-07T09:13:35.507 に答える