gpt4 book ai didi

perl - 如何在100个文本文件上的 'search and replace'上以20k项执行最小磁盘I/O(每个行有5万行)

转载 作者:行者123 更新时间:2023-12-02 09:07:39 25 4
gpt4 key购买 nike

我想用非结构化文本对大约100个数据文件进行“搜索和替换”。每个文件的大小约为50 MB,每行50k。大约有2万个词要搜索和替换,这些词存储在另一个文件中。 'terms_list.csv',一个CSV格式的文件,具有三列COL1,COL2和COL3。我需要在100个数据文件的每一个中搜索'terms_list.csv'的COL1和COL2中的单词,如果找到两个单词中的任何一个,则用COL3中的相应单词替换。

利用我对Shell脚本的基本知识,我使用AWK / SED循环编写了以下Shell脚本。它从2万行“terms_list.csv”中逐行读取,并在100个文件中的每个文件中搜索COL1和COL2,如果找到,将替换为COL3。

for DATA_FILE in $(ls text_data_file_*.csv) #Data files (100 files) with 50k lines; contain terms in COL1 and COL2 of terms_list.csv
do
while read -r line;
do
x=$(echo $line | awk -F',' '{print $1}'); \
y=$(echo $line | awk -F',' '{print $2}'); \
z=$(echo $line | awk -F',' '{print $3}'); \
echo "File: " $DATA_FILE " x: "$x "|" "y: "$y "|" "z: "$z ; \
sed -i "s/$x/$z/;s/$y/$z/g" $DATA_FILE
done < terms_list.csv #20k lines in CSV format; each with search terms COL1,COL2, and replace term COL3
done

我肯定有比上面更好/有效的代码来完成任务,因为这需要大量的磁盘读/写操作。有什么建议可以改善吗?如果有更好的工具(perl / python)可以完成此任务,请您给我一些建议/指导。

以下是两个文件的样本数据:
  • “text_data_file_0001.csv”:100个数据文件之一,“text_data_file_0001.csv”包含以下非结构化数据,其中包含文本中的“TermFull”和“TermAbbreviated”。 [每个文件的大小约为50 MB和5万行]
    ID000001,Mangifera indica, commonly known as mango, is a species of flowering plant in the sumac and poison ivy family Anacardiaceae. M. indica is a popular fruit in India. 
    ID000002,Oryza sativa, commonly known as Asian rice, is the plant species most commonly referred to in English as rice. O. sativa contains two major subspecies: the sticky, short-grained japonica or sinica variety, and the nonsticky, long-grained indica rice variety.
  • 'terms_list.csv'文件:搜索项'TermFull'和'TermAbbreviated'以及替换项'TermJoined'存储在'terms_list.csv'中,包含20k行,如下所示
    TermFull,TermAbbreviated,TermJoined
    Mangifera indica,M. indica,Mangiferaindica
    Oryza sativa,O. sativa,Oryzasativa
  • 所需的输出文件“text_data_file0001.csv”如下所示,其中“TermFull”和“TermAbbreviated”替换为“TermJoined”
    ID000001,Mangiferaindica, commonly known as mango, is a species of flowering plant in the sumac and poison ivy family Anacardiaceae. Mangiferaindica is a popular fruit in India. 
    ID000002,Oryzasativa, commonly known as Asian rice, is the plant species #most commonly referred to in English as rice. Oryzasativa contains two major subspecies: the sticky, short-grained japonica or sinica variety, and the nonsticky, long-grained indica rice variety.
  • 最佳答案

    您可以使用sed从terms_list.csv构建sed脚本:

    sed '1d;s/,/|/;s|,|/|;s|.*|s/&/g|' terms_list.csv

    其工作原理如下:

    1d           # Skip the first line
    s/,/|/ # Replace the first comma with a pipe
    s|,|/| # Replace the second comma with a slash
    s|.*|s/&/g| # Wrap each line in s/ and /g

    并具有以下输出:
    $ sed '1d;s/,/|/;s|,|/|;s|.*|s/&/g|' terms_list.csv
    s/Mangifera indica|M. indica/Mangiferaindica/g
    s/Oryza sativa|O. sativa/Oryzasativa/g

    现在,我们使用此输出在我们要更改的所有文件上运行 sed -i(需要GNU sed进行就地编辑):
    sed '1d;s/,/|/;s|,|/|;s|.*|s/&/g|' terms_list.csv | sed -i -Ef- text_data_file_*.csv
  • -E启用扩展的正则表达式,因此我们可以使用|进行替换
  • -f-从标准输入
  • 读取sed命令


    就显式单词边界而言,可以使第一个命令更健壮,以避免子字符串匹配:
    $ sed '1d;s/,/|/;s|,|)\\b/|;s|.*|s/\\b(&/g|' terms_list.csv
    s/\b(Mangifera indica|M. indica)\b/Mangiferaindica/g
    s/\b(Oryza sativa|O. sativa)\b/Oryzasativa/g

    其中 \b表示单词边界(也是GNU sed扩展名)。

    如果输入中包含任何正则表达式元字符,我们必须将其全部转义,因此第一个命令将变为如下所示:
    sed '1d;s/[][*+{}()/\|&^$.?]/\\&/g;s/,/|/;s|,|)\\b/|;s|.*|s/\\b(&/g|' terms_list.csv

    这里重要的补充是第一个替换,通过用反斜杠转义来处理元字符:
    s/[][*+{}()/\|&^$.?]/\\&/g

    因此,对于最坏的情况, terms_list.csv包含类似
    a[abc]*x+\1{2}|-(o).^$?/\a,other,abc&\1def

    生成的命令看起来像
    s/\b(a\[abc\]\*x\+\\1\{2\}\|-\(o\)\.\^\$\?\/\\a|other)\b/abc\&\\1def/g

    在某些情况下,这还没有涵盖:如果输入的CSV文件在一个字段中包含逗号,则必须诉诸CSV解析器进行预处理。在第三个解决方案中转义正则表达式元字符时,将忽略逗号。

    关于perl - 如何在100个文本文件上的 'search and replace'上以20k项执行最小磁盘I/O(每个行有5万行),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56156505/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com