我正在尝试删除从单个文件中获得的 700,000 条数据,这些数据需要针对多个文件中存在的 1500 万条数据进行删除。
示例:700 000 的 1 个文件称为 A。具有 1500 万的多个文件池称为 B。 我想要一个没有文件 A 数据的文件池 B。
下面是我尝试使用的 shell 脚本,它工作正常。但这需要花费 8 多个小时的大量时间进行擦洗。
IFS=$'\r\n' suppressionArray=($(cat abhinav.csv1))
suppressionCount=${#suppressionArray[@]}
cd /home/abhinav/01-01-2015/
for (( j=0; j<$suppressionCount; j++));
do
arrayOffileNameInWhichSuppressionFound=`grep "${suppressionArray[$j]}," *.csv| awk -F ':' '{print $1}' > /home/abhinav/fileNameContainer.txt`
IFS=$'\r\n' arrayOffileNameInWhichSuppressionFound=($(cat /home/abhinav/fileNameContainer.txt))
arrayOffileNameInWhichSuppressionFoundCount=${#arrayOffileNameInWhichSuppressionFound[@]}
if [ $arrayOffileNameInWhichSuppressionFoundCount -gt 0 ];
then
echo -e "${suppressionArray[$j]}" >> /home/abhinav/emailid_Deleted.txt
for (( k=0; k<$arrayOffileNameInWhichSuppressionFoundCount; k++));
do
sed "/^${suppressionArray[$j]}/d" /home/abhinav/06-07-2015/${arrayOffileNameInWhichSuppressionFound[$k]} > /home/abhinav/06-07-2015/${arrayOffileNameInWhichSuppressionFound[$i]}".tmp" && mv -f /home/abhinav/06-07-2015/${arrayOffileNameInWhichSuppressionFound[$i]}".tmp" /home/abhinav/06-07-2015/${arrayOffileNameInWhichSuppressionFound[$i]}
done
fi
done
我想到的另一个解决方案是将 700k 数据分解为 50K 的较小文件,并发送到 5 个可用的服务器上,同时 POOL A 将在每个服务器上可用。 每个服务器将提供 2 个较小的文件。
最佳答案
这两行很奇特:
arrayOffileNameInWhichSuppressionFound=`grep "${suppressionArray[$j]}," *.csv| awk -F ':' '{print $1}' > /home/abhinav/fileNameContainer.txt`
IFS=$'\r\n' arrayOffileNameInWhichSuppressionFound=($(cat /home/abhinav/fileNameContainer.txt))
第一个为一英里长的变量名分配一个空字符串,因为标准输出被定向到文件。第二个然后将该文件读入数组。 ('很好奇名字不是arrayOfFileNameInWhichSuppressionFound
,但是file
的小写f
是一致的,所以我猜不是除了使变量名称更难阅读之外,这很重要。)
可以简化为:
ArrFileNames=( $(grep -l "${suppressionArray[$j]}," *.csv) )
您不需要在 IFS 中继续使用回车符;要么永久设置它,要么确保在开始之前没有回车。
您正在运行这些循环 7,00,000 次(使用印度表示法)。好多啊。难怪要花几个小时。您需要将事物组合在一起。
您可能应该简单地从 abhinav.csv1
中提取行并安排将它们转换为适当的 sed
命令,然后将它们拆分并应用它们。沿着:
sed 's%.*%/&,/d%' abhinav.csv1 > names.tmp
split -l 500 names.tmp sed-script.
for script in sed-script.*
do
sed -f "$script" -i.bak *.csv
done
这使用 -i
选项来备份文件。如果您的 sed
不支持 -i
选项,则可能需要显式进行重定向:
for file in *.csv
do
sed -f "$script" "$file" > "$file.tmp" &&
mv "$file.tmp" "$file"
done
您应该试验一下脚本的大小。我在 split
命令中选择了 500 作为适度的折衷。除非您使用的是老式 HP-UX,否则应该是安全的,但您可以增加脚本的大小,这将减少您必须编辑每个文件的次数,从而加快处理速度。如果你可以使用 5,000 或 50,000,你应该这样做。实验看上限是多少。我不确定您是否会发现一次处理所有 700,000 行是否可行 — 但如果您能那样做,那应该是最快的。
关于linux - 试图将 700,000 个数据与 1500 万个数据删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31309159/