use*_*029 3 grep awk perl text-processing
我有一个包含 2 列数据的文件。我需要从每列中找到具有公共字符串的行。我只对逐行的匹配感兴趣,而不是来自第 1 列第 10 行和第 2 列第 3 行的匹配字符串。
我的文件:
023q 023q023q
0adc 0adc0adc
123456 123456
abcde abcdefg
08tgdf 90alkhg
Run Code Online (Sandbox Code Playgroud)
因此,在此示例中,除最后一行之外的每一行都共享一个公共字符串,该行的一部分或这些行是相同的,这就是我需要找到的。我已经从 2 个文件中看到了关于常见字符串的大量问题和线索,但到目前为止我的确切用例还没有。
更新:每行至少需要匹配 4 个字符。
短暂的呆呆方法:
awk '(index($1, $2) !=0 && length($2) >= 4) || (index($2, $1) !=0 && length($1) >= 4)' file
Run Code Online (Sandbox Code Playgroud)
输出:
023q 023q023q
0adc 0adc0adc
123456 123456
abcde abcdefg
Run Code Online (Sandbox Code Playgroud)
index(in, find)
在字符串in 中搜索字符串find的第一次出现,并返回该出现在字符串in 中开始的字符位置。
对于更复杂的情况,当我们需要在 2 个输入字符串上找到长度至少为 4 个字符的最长公共子字符串时 - 我建议使用Python 方法:
假设输入文件有点“复杂”并且有以下几行:
1023q 023q023q
v0adc 20adc0adc
s123456 123456
eabcde cabcdefg
08tgdf 90alkhg
Run Code Online (Sandbox Code Playgroud)
为了找到最长的公共子串,我们将使用difflib模块中的SequenceMatcher类。
find_common_lines.py 脚本:
import re
from difflib import SequenceMatcher
with open('filename', 'r') as fh:
for l in fh.read().splitlines():
items = re.findall(r'\S+', l.strip()) # getting 2 comparable strings
m = SequenceMatcher(None, items[0], items[1]).find_longest_match(0, len(items[0]), 0, len(items[1]))
if m.size >= 4:
print(l)
Run Code Online (Sandbox Code Playgroud)
用法(您可能有另一个python 3.x版本,当前案例已在python 3.5上测试过):
python3.5 find_common_lines.py
Run Code Online (Sandbox Code Playgroud)
输出:
1023q 023q023q
v0adc 20adc0adc
s123456 123456
eabcde cabcdefg
Run Code Online (Sandbox Code Playgroud)