我在一个文件夹中有数千个csv文件。每个文件都有128,000个条目,每行有四列。 有时(每天两次)我需要将列表(10,000个条目)与所有csv文件进行比较。如果其中一个条目与其中一个csv文件的第三列或第四列相同,我需要将整个csv行写入一个额外的文件。
#!/bin/bash
getArray() {
array=()
while IFS= read -r line
do
array+=("$line")
done < "$1"
}
getArray "entries.log"
for e in "${array[@]}"
do
echo "$e"
/bin/grep $e ./csv/* >> found
done
这似乎有效,但它会持续下去。在将近48小时后,该脚本仅检查了大约10,000个条目中的48个条目。
下一个尝试是将所有csv文件导入mysql数据库。但是我的桌子上有大约50,000,000个条目存在问题。 所以我编写了一个脚本,在49,000,000个条目之后创建了一个新表,因此我能够导入所有csv文件。 我试图在第二列创建一个索引,但它总是失败(超时)。在导入过程不可能之前创建索引。它将导入速度减慢到几天而不是几个小时。 选择声明很糟糕,但它奏效了。比“grep”解决方案快得多,但仍然会变慢。
我还可以尝试在csv文件中搜索什么? 为了加快速度,我将所有csv文件复制到ssd。但我希望还有其他方法。
答案 0 :(得分:0)
这不太可能为您提供有意义的好处,但对您的脚本进行了一些改进
使用内置的mapfile
将文件粘贴到数组中:
mapfile -t array < entries.log
将grep与模式和适当标志文件一起使用。
我假设您希望将entries.log中的项目与固定字符串匹配,而不是正则表达式模式 我还假设你想要匹配整个单词。
grep -Fwf entries.log ./csv/*
这意味着您不必花费1000次csv文件(对于entries.log中的每个项目一次)。实际上,仅此应该为您提供真正有意义的性能提升。
这也消除了将entries.log读入数组的需要。
答案 1 :(得分:0)
您可以构建一个模式文件,然后使用xargs
和grep -Ef
来搜索批量csv文件中的所有模式,而不是像当前解决方案中那样一次搜索一个模式:
# prepare patterns file
while read -r line; do
printf '%s\n' "^[^,]+,[^,]+,$line,[^,]+$" # find value in third column
printf '%s\n' "^[^,]+,[^,]+,[^,]+,$line$" # find value in fourth column
done < entries.log > patterns.dat
find /path/to/csv -type f -name '*.csv' -print0 | xargs -0 grep -hEf patterns.dat > found.dat
find ...
- 发出所有找到的csv文件的NUL分隔列表xargs -0 ...
- 将文件列表批量传递给grep 答案 2 :(得分:0)
在awk中假设所有csv文件都发生了变化,否则跟踪已经检查过的文件是明智的。但首先是一些测试材料:
$ mkdir test # the csvs go here
$ cat > test/file1 # has a match in 3rd
not not this not
$ cat > test/file2 # no match
not not not not
$ cat > test/file3 # has a match in 4th
not not not that
$ cat > list # these we look for
this
that
然后是剧本:
$ awk 'NR==FNR{a[$1];next} ($3 in a) || ($4 in a){print >> "out"}' list test/*
$ cat out
not not this not
not not not that
说明:
$ awk ' # awk
NR==FNR { # process the list file
a[$1] # hash list entries to a
next # next list item
}
($3 in a) || ($4 in a) { # if 3rd or 4th field entry in hash
print >> "out" # append whole record to file "out"
}' list test/* # first list then the rest of the files
该脚本将所有列表条目哈希到a
并通过csv文件读取,以便在匹配时查找哈希输出中的第3和第4个字段条目。
如果您测试它,请告诉我它运行了多长时间。