【发布时间】:2019-02-22 23:38:38
【问题描述】:
tl;dr:我想在 600k 行 csv 中使用 3 个不同过滤器匹配的 col 条目更改列值,该怎么做?
我有几个超过 600,000 行的数据文件。它们看起来像这样:
random.website.com|1000002644|FunGRP_1000009280_OT|5556667777@random.website.com|User|5556667777|main|Y|6557|main||6557|
我想在匹配时将第 8 列的值 Y/N 更改为 N。
我有一个存储在换行符分隔的文本文件中的第 2 列(企业)第 3 列(组)和第 6 列(电话号码)的过滤器列表,如下所示:
电话号码
5553690049
5553690050
5553690052
...
企业
Loud-YPOxXTFF
res-http
1700000004
...
组
FunGRP_1000009280_OT
1300000004_CollabGrp_1
HostedVKL_1300000035_SA
...
现在我有一个 bash 程序,它遍历数据中的每个条目,提取我想用 awk 过滤的列(这意味着 1800k awk 调用),然后在每个要检查的内容上循环三次,然后读取每个循环过滤,然后检查过滤器是否与项目匹配。如果是,则 awk 行(第 4 awk)以替换第 8 列并将其填充到输出文件中。如果没有过滤器与该行匹配,则只需将未更改的行放在输出文件中。这是非常低效的,但它确实有效。代码如下:
filter () {
while read -r entry || [[ -n "$entry" ]]; do
phone="$(echo "$entry" | awk -F "|" '{ print $6 }')"
group="$(echo "$entry" | awk -F "|" '{ print $3 }')"
enterprise="$(echo "$entry" | awk -F "|" '{ print $2 }')"
to_test=("$phone" "$group" "$enterprise")
filters=("$NUMBER_FILTER_FILE" "$GROUP_FILTER_FILE" "$ENTERPRISE_FILTER_FILE")
count=-1
matched=""
for item in "${to_test[@]}"; do
count=$(( count+1 ))
if [[ -n "$item" ]] && [[ -f "${filters[$count]}" ]]; then
while read -r filter || [[ -n "$filter" ]]; do
if [[ "$item" = "$filter" ]]; then
echo "$entry" | awk -F "|" 'BEGIN {OFS = FS} $8="N" {print}' >> "$WORKING$OUTPUTFILE"
matched="true"
continue 2
fi
done < "${filters[$count]}"
fi
done
# If no filter matches, put the original entry in the output
[[ -z "$matched" ]] && echo "$entry" >> "$WORKING$OUTPUTFILE"
done < "$WORKING$UNFILTEREDOUTPUTFILE"
}
我需要这样更有效率,我觉得在 bash 中这样做很愚蠢,这就是我在这里标记 python 的原因。我对python很熟悉。
我已经打算通过将 awk 调用移出循环来捕获每一整列来改进它。像PHONENUM_COL=($(awk '{FS = "|"} {print $6}' data.txt)) 这样的东西。然后(假设它们最终的长度相同)我可以循环遍历数组的长度并匹配如下内容:
[[ "PHONE_COL[$COUNT]" = "$filter" | "GROUP_COL[$COUNT]" = "$filter" | "ENTERPRISE_COL[$COUNT]" = "$filter" ]]
我正在更新的原始程序是用 bash 编写的,这就是为什么我继续尝试在 shell 脚本中解决这个问题,但我不是 bash 的向导,所以我开始研究 python + pandas这样做是因为我觉得这应该更容易。任何建议、策略或想法都会有所帮助。谢谢。
【问题讨论】:
-
如果我理解正确,
ith 行是否匹配其电话号码、组或企业是否与这些文件中的ith 条目匹配?不是说它匹配任何文件中的任何条目,对吧? -
是的,如果任何过滤器与所考虑的 3 个相应术语之一匹配,则该行匹配,我们将
$8切换为N