我有一个15000行的CSV文件。从列表中我想删除不需要的产品/制造商。我有一个包含制造商和源CSV文件的列表。
我发现sed会合适但我会在循环中闲逛。
while read line
do
unwanted = $
sed "|"$unwanted|d" /home/arno/pixtmp/pixtmp.csv >/home/arno/pixtmp/pix-clean.c$
done < /home/bankey/shopimport/unwanted.txt
感谢任何帮助。
Inputfile中:
耗材; Inktpatronen voor打印机; Inkt voor打印机; B0137790; HP; Pakket 2 inktpatronen No339 - Zwart + Papier Goodway - 80 g /m² - A4 - 500 vel; Dit pakket van 2 inktpatronen nr 339 zijn ontworpen voor uw HP打印机en leveren afdrukken van kwaliteit .; 47.19; 6.99; 47.19; http://pan8.fotovista.com/dev/8/5/32150358/l_32150358.jpg; in stock; 0.2; 0.11201; 9.99 ;; C9504EE; 0 ;;答案 0 :(得分:1)
我分两步使用sed
:
sed
脚本。那可能是:
unwanted=/home/bankey/shopimport/unwanted.txt
datafile=/home/arno/pixtmp/pixtmp.csv
cleaned=/home/arno/pixtmp/pix-clean.csv
sed 's%.*%/,&,/d%' $unwanted > sed.script
sed -f sed.script $datafile > $cleaned
rm -f sed.script
第一次调用sed
只需用sed
命令替换描述不需要记录的每一行的内容,该命令将其删除为数据行中间的逗号分隔字段。如果你必须在开头或结尾处理不需要的字段,那么你必须更加努力。如果可能存在嵌入式斜杠,逗号,引号等,您还必须更加努力。sed
的第二次调用将第一次创建的脚本应用于数据文件,生成已清理的文件。
您可以通过确保脚本文件名是唯一的来改进它,并在进程被中断时捕获脚本文件:
tmp=$(mktemp /tmp/script.XXXXXX)
trap "rm -f $tmp; exit 1" 0 1 2 3 13 15 # EXIT, HUP, INT, QUIT, PIPE, TERM
unwanted=/home/bankey/shopimport/unwanted.txt
datafile=/home/arno/pixtmp/pixtmp.csv
cleaned=/home/arno/pixtmp/pix-clean.csv
sed 's%.*%/,&,/d%' $unwanted > $tmp
sed -f $tmp $datafile > $cleaned
rm -f $tmp
trap 0 # Cancel the exit trap
使用GNU sed
,但不能使用Mac OS X(BSD)sed
,因此可以避免使用中间文件:
unwanted=/home/bankey/shopimport/unwanted.txt
datafile=/home/arno/pixtmp/pixtmp.csv
cleaned=/home/arno/pixtmp/pix-clean.csv
sed 's%.*%/,&,/d%' $unwanted |
sed -f - $datafile > $cleaned
这告诉第二个sed
从标准输入读取其脚本。如果您拥有bash
版本4.x(在Mac OS X上不是标准版),则可以使用流程替换:
unwanted=/home/bankey/shopimport/unwanted.txt
datafile=/home/arno/pixtmp/pixtmp.csv
cleaned=/home/arno/pixtmp/pix-clean.csv
sed -f <(sed 's%.*%/,&,/d%' $unwanted) $datafile > $cleaned
答案 1 :(得分:0)
您必须确保每个循环周期将上一个周期的输出文件作为输入文件,否则您将使用原始文件的内容减去最后一个不需要的记录来覆盖输出文件。
如果您的sed
命令支持内联编辑(选项-i
),您可以这样做:
cp /home/arno/pixtmp/pixtmp.csv /home/arno/pixtmp/pix-clean.csv
while read line; do
sed -i "/$line/d" /home/arno/pixtmp/pix-clean.csv
done < /home/bankey/shopimport/unwanted.txt
否则你必须自己处理临时文件:
cp /home/arno/pixtmp/pixtmp.csv /home/arno/pixtmp/pix-clean.csv
while read line; do
sed "/$line/d" /home/arno/pixtmp/pix-clean.csv >/home/arno/pixtmp/pix-clean.c$
mv -f /home/arno/pixtmp/pix-clean.c$ /home/arno/pixtmp/pix-clean.csv
done < /home/bankey/shopimport/unwanted.txt
答案 2 :(得分:0)
sed
不如awk
。例如,假设您的输入文件和不受欢迎的术语列表以空格分隔,您可以执行以下操作:
awk 'NR==FNR { a[$0]++ } NR != FNR && !a[$1]' undesired input
这将打印出文件'input'文件,省略第一列与文件undesired
中的一行匹配的任何行。