我得到一个输入文件vendor.csv,其中有一个名为retailer的列。 我有一个有效零售商值的预定义列表,即a,b,c。如果'd'进入零售商列,我将不得不采取一些行动,主要是将其回显给日志并停止处理并通知用户。
到目前为止,我已完成以下操作
f1=/stage/Scripts/ecommerce/vendor/final*.csv
k=`cut -d, -f1 $f1 |sort -u`
echo $k
这给了我
a b c d
上述o / p不是逗号分隔
对于上述情况
,我可以将有效值a b c存储在文件或字符串中我现在如何检查?这是最好的方式吗
有效值为ALB/SFY Total Ecom TA Peapod Total Ecom TA Target Total Ecom TA
现有数据包含以下唯一数据点
ALB/SFY Total Ecom TA Hy-Vee Total Ecom TA Peapod Total Ecom TA Target Total Ecom TA
因此“Hy-Vee Total Ecom TA”是无效值。
这是我尝试使用grep
$ echo $s
ALB/SFY Total Ecom TA Peapod Total Ecom TA Target Total Ecom TA
echo $k
ALB/SFY Total Ecom TA Hy-Vee Total Ecom TA Peapod Total Ecom TA Target Total Ecom TA
grep -v "$s" "$k"
它给了我一个错误
grep: ALB/SFY Total Ecom TA
Hy-Vee Total Ecom TA
Peapod Total Ecom TA
Target Total Ecom TA: No such file or directory
有些解决方案以正确的方式指出了我,在R中,我会将上述任务作为
valid_values = ['a','b','c']
invalid_retailer = unique(vendorfile$retailer) %not% in valid_values
我试图在shell中复制相同的进程,因此我使用了cut和grep。
答案 0 :(得分:3)
尝试awk命令,这是非常精炼的。
awk -F',' '{if (($1 == "a") || ($1 == "b") || ($1 == "c") || ($1 == "d")) print $0 }' /stage/Scripts/ecommerce/vendor/final*.csv
其他方式::
我们可以逐行分配所有零售商ID,例如retailer.txt
。 retailer.txt
的内容就像
a
b
要打印与retailer.txt
中的零售商ID匹配的第一个字段(分隔开),请使用以下命令:
awk -F',' 'FNR==NR{$1=a[$1];next} ($1 in a)' retailer.txt final*.csv
答案 1 :(得分:1)
或许这样的事情?
awk -F, 'NR==FNR { ++a[$1]; next }
!a[$1] { print FILENAME ":" FNR ": Invalid label " $1 >>"/dev/stderr" }' valid.txt final*.csv
其中valid.txt
包含您的有效标签,每行一个。
awk 'NR==FNR { ++a[$1] }'
的一般模式是将一组文件中的第一个读入内存中的数组的常用方法,然后在脚本的其余部分执行某种类型的连接(在数据库意义上)其他输入文件中的字段。 Awk一次只处理一行,所以其他文件实际上可以任意大。但是,您确实需要能够将第一个文件中的数据存储在内存中。
优于基本cut
+ grep
尝试的优势在于我们可以打印整个输入行,而不仅仅是告诉您哪些标签无效并让您返回并手动找出哪些行哪些文件实际包含违规行为。
切线,您的grep
尝试有很多问题。首先,如果您处理的不仅仅是玩具数据,那么您希望避免将数据存储在shell变量中。其次,您可能想要调整选项以告诉grep
您希望按字面匹配文字(-F
- 如果没有这个,a.c
匹配abc
,因为点是例如,正则表达式通配符,并且您希望匹配覆盖整行(-x
- 如果没有这个,b
匹配abc
,因为它是一个子字符串)。
cut -d, -f1 final*.csv | sort -u |
grep -vxFf valid.txt
-f
filename 选项表示从文件读取模式,没有其他文件名,grep
处理标准输入(在这种情况下来自管道)
答案 2 :(得分:-1)
grep
无法做你想做的事情吗?
如果我理解,使用正确的正则表达式在您的csv文件上调用grep
可以使用错误的零售商打印所有行。
你需要选择一个强大的正则表达式以防止误报,但我需要输入示例来帮助你......
或者,如果正则表达式不能防止误报,你可以使用grep after cut命令,如下所示:
for bad_retailer in $(cut -d, -f1 $f1 | grep d) ; do echo $bad_retailer ; done
带有坏零售商的名字。
如果您想跟踪多个不良零售商,可以使用grep -E "d|g|h"
,以及坏零售商的d和g和h名称。