我有这个读取文件的脚本,文件如下:
711324865,438918283,2
-333308476,886548365,2
1378685449,-911401007,2
-435117907,560922996,2
259073357,714183955,2
...
脚本:
#!/bin/bash
while IFS=, read childId parentId parentLevel
do
grep "\$parentId" parent_child_output_level2.csv
resul=$?
echo "child is $childId, parent is $parentId parentLevel is $parentLevel resul is $resul"
done < parent_child_output_level1.csv
但它不起作用,结果总是让我回归1,这是误报。
我知道因为我可以启动下一个命令,相当于我认为:
[core@dub-vcd-vms165 generated-and-saved-to-hdfs]$
grep "\-911401007"parent_child_output_level2.csv
-911401007,-157143722,3
请帮忙。
答案 0 :(得分:3)
grep命令只打印负数。
$ grep -oP '(^|,)\K-\d+' file.csv
-333308476
-911401007
-435117907
(^|,)
匹配行或逗号的开头。\K
会丢弃之前匹配的字符。 -\d+
匹配-
以及以下一个或多个数字。答案 1 :(得分:2)
您的标题与您的问题不一致。你的标题询问如何grep负数,Avinash Raj回答得很好,虽然我建议你甚至不需要(Perl风格)后视正面断言(^|,)\K
来匹配起始字段,因为如果文件格式正确,那么-\d+
也会匹配所有数字。所以你可以运行(编辑:意识到领先 - 你需要 - 防止grep将模式作为选项):
grep -oP -- '-\d+' file.csv;
您的问题包括一个脚本,其目的似乎是对另一个文件的第二个字段(parentId)中出现的一个文件(parent_child_output_level2.csv)的第一个字段(childId)中的任何数字(正面或负面)进行grep (parent_child_output_level1.csv)。为了实现这一点,我不会使用grep,因为你正在尝试进行精确的数值相等测试,这甚至可以作为一个精确的字符串相等测试来完成,假设你的数字总是一致地表示(例如没有冗余的前导零)。反复浏览整个文件只是为了在一列中搜索一个数字也浪费了CPU。
这就是我要做的事情:
parentIdList=($(cut -d, -f2 parent_child_output_level1.csv));
childIdList=($(cut -d, -f1 parent_child_output_level2.csv));
for parentId in "${parentIdList[@]}"; do
for childId in "${childIdList[@]}"; do
if [[ "$childId" == "$parentId" ]]; then
echo "$parentId";
fi;
done;
done;
使用此方法,您只需预先计算父ID列表和子ID列表一次,使用cut从每个文件中提取相应的字段。然后你可以使用shell-builtin for循环,shell-builtin if条件,shell-builtin [[test命令完成检查,最后用shell-builtin echo完成打印匹配。在运行剪切外部可执行文件的初始命令替换之后,所有内容都是shell-builtin。
如果 想要在负数上过滤这些结果,您可以在上述脚本的结果中使用^-
,或者在每个结果中使用grep(或者只是第一个)剪切命令,或在外部for循环内添加以下行:
if [[ "${parentId:0:1}" != '-' ]]; then continue; fi;
替代方法:
if [[ "$parentId" != -* ]]; then continue; fi;
任何一种方法都会跳过非负面的。