自动计算出现次数

Rhe*_*hea 3 command-line text-processing

我想知道 'ABCD'(文件 A)在 DB(文件 B)中出现了多少次。同样,我想知道文件 A 中针对 DB 的每一行。我需要一个可以简化我的工作的自动化命令,因为我在文件 A 中有大量数据,我想在许多数据库中搜索它。我只是为了理解而将字符加粗。

文件A

ABCD
EFG
HIJKL
MNO
PQRSTU
Run Code Online (Sandbox Code Playgroud)

文件B

XYZ ABCD FORNTUFPSRWSABCFYWSZCFTHBFORTYBJNF ABCD D EFG ACVRT EFG PQRMNOOPQ EFG ZXXXYY

期望的输出:

ABCD  2
EFG   3
HIJKL 4567
MNO   0
PQRSTU 7652
Run Code Online (Sandbox Code Playgroud)

Ser*_*nyy 6

Python

count_patterns.py脚本。对于大文件应该相当不错。用于OrderedDict记录命令行提供的文件 A 中的所有模式,并在文件 B 中搜索它们。

#!/usr/bin/env python3
import sys
from collections import OrderedDict

with open(sys.argv[1]) as pattern_file, open(sys.argv[2]) as data_file:
    patterns = OrderedDict.fromkeys(map(str.strip, pattern_file), 0)

    for line in data_file:
        for p in patterns:
            patterns[p] += line.count(p)

for kv in patterns.items():
    print(*kv)
Run Code Online (Sandbox Code Playgroud)

用法:

$ ./count_patterns.py file_A.txt file_B.txt 
ABCD 4
EFG 3
HIJKL 0
MNO 1
PQRSTU 0
Run Code Online (Sandbox Code Playgroud)

Bash 方法。

这使用进程替换sed,让我们将文件 A 拆分为在 处的换行符**,并用于grep -c计算匹配行的数量。

$ cat file_B.txt 
ABCD**FORNTUFPSRWSABCFYWSZCFTHBFORTYBJNF**ABCD**D**EFG**ACVRT**EFG**PQRMNOOPQ**EFG**ZXXXYY
ABCD**FORNTUFPSRWSABCFYWSZCFTHBFORTYBJNF**ABCD

$ cat file_A.txt 
ABCD
EFG
HIJKL
MNO
PQRSTU

$ while IFS= read -r pattern;  do  printf "%s\t" "$pattern";   grep -c "$pattern" < <( sed 's/\*\*/\n/g' file_B.txt ); done  < file_A.txt 
ABCD    4
EFG 3
HIJKL   0
MNO 1
PQRSTU  0
Run Code Online (Sandbox Code Playgroud)

不是最好的方法,可能不适合大文件,但有效。不推荐使用 bash 方法,但如果数据集不大,它会起作用。


Rav*_*ina 6

我的建议是:

IFS=; while read -r word; do printf "%s " $word; grep -o $word b | wc -l; done < a
Run Code Online (Sandbox Code Playgroud)
  • 使用whilewe 循环成单词(文件 a)
  • printf "%s " $word : 打印单词名称,例如:ABCD
  • grep -o $word b | wc -l: 计​​数并打印出现次数


Dav*_*ter 5

重击

使用 Bash 的关联数组

#!/bin/bash
set -eu
declare -A patterns

while IFS= read -r p; do
    patterns["$p"]=0
done < "$1"

while IFS='*' read -ra l; do
    for r in "${l[@]}"; do
        if [ -n "$r" ] && [ -v patterns["$r"] ]; then
            patterns[$r]=$((${patterns["$r"]} + 1))
        fi
    done
done < "$2"

for p in "${!patterns[@]}"; do
    printf '%s\t%u\n' "$p" "${patterns["$p"]}"
done
Run Code Online (Sandbox Code Playgroud)

用法:

bash count-patterns.sh pattern-list.txt word-list.txt
Run Code Online (Sandbox Code Playgroud)

蟒蛇 3

使用自定义字典类和功能样式数据处理:

bash count-patterns.sh pattern-list.txt word-list.txt
Run Code Online (Sandbox Code Playgroud)

用法:

python3 count-patterns.py pattern-list.txt word-list.txt
Run Code Online (Sandbox Code Playgroud)

C++

#!/usr/bin/env python3
import sys, itertools, collections

class MyCounter(collections.UserDict):
    def __init__(self, _dict):
        self.data = _dict

    def update(self, iterable):
        for key in iterable:
            self.data[key] += 1

with open(sys.argv[1]) as pattern_file:
    patterns = MyCounter({ s.rstrip('\n'): 0 for s in pattern_file })

with open(sys.argv[2]) as wordlist_file:
    patterns.update(filter(patterns.__contains__,
        itertools.chain.from_iterable(map(
            lambda s: s.rstrip('\n').split('**'), wordlist_file))))

for p in patterns.items():
    print(*p, sep='\t')
Run Code Online (Sandbox Code Playgroud)

编译:

c++ -std=c++11 -o count-patterns count-patterns.cpp
Run Code Online (Sandbox Code Playgroud)

用法:

./count-patterns pattern-list.txt word-list.txt
Run Code Online (Sandbox Code Playgroud)