2013-01-20 35 views
1

我有一个15000行的CSV文件。从列表中我想删除不需要的产品/制造商。我有一个制造商和源CSV文件的列表。howto loop sed获取变量

我发现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 - 兹瓦特+纸业顺行 - 为80g /平方米 - A4 - 500 VEL;秩pakket面包车2 inktpatronen NR 339 zijn ontworpen voor uw HP printer 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

您可以显示输入文件和预期输出的内容是什么? – cmbuckley

+1

听起来像典型的awk工作。但没有输入/预期输出,很难找到起点。 – Kent

+0

@JonathanLeffler我搞清楚哪一个实际上是最好的......但tnx的建议.. –

回答

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 
+0

tnx..someting这样我也想出了..也很好..在此期间,我打了nxt停止.. –

+0

而读线;做 sed --in-place“/ $ line/d”/home/arno/pixtmp/pixtmp.csv done

0

sed不太适合比awk 。例如,假设您的输入文件和你不想要的条款清单是空间分隔的,你可以简单地做:

awk 'NR==FNR { a[$0]++ } NR != FNR && !a[$1]' undesired input 

这将打印出来的文件“输入”文件,省略其中的第一列相匹配的任何行行undesired

1

我会分两步使用sed

  1. 从不需要的信息创建sed脚本。
  2. 将创建的脚本应用于数据文件。

这可能是:

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 
+0

嗯..我想我会重写剧本,把这些线..非常甜.. tnx .. –