根据另一个文件中找到的行从文件中删除行

根据另一个文件中找到的行从文件中删除行

文件 file1.txt 包含如下行:

/api/purchase/<hash>/index.html

例如:

/api/purchase/12ab09f46/index.html

文件 file2.csv 包含如下行:

<hash>,timestamp,ip_address

例如:

12ab09f46,20150812235200,22.231.113.64 
a77b3ff22,20150812235959,194.66.82.11

我想过滤 file2.csv,删除 file1.txt 中也存在哈希值的所有行。也就是说:

cat file1.txt | extract <hash> | sed '/<hash>/d' file2.csv

或类似的东西。

它应该很简单,但我似乎无法使其发挥作用。

任何人都可以提供此任务的工作管道吗?

答案1

cut -d / -f 4 file1.txt | paste -sd '|' | xargs -I{} grep -v -E {} file2.csv

解释:

cut -d / -f 4 file1.txt将从第一个文件中选择哈希值

paste -sd '|'将把所有哈希值连接成一个正则表达式 ex。H1|H2|H3

xargs -I{} grep -v -E {} file2.csv将使用先前的模式作为参数调用 grep,xargs 将替换{}STDIN

如果你没有,paste你可以用它替换它tr "\\n" "|" | sed 's/|$//'

答案2

可能的awk解决方案:

awk 'NR == FNR { x[$4] = 1; next; } { if (!($1 in x)) print $0; }' FS="/" file1.txt FS="," file2.txt

首先,我们file1.txt使用FS(字段分隔符)“/”进行读取,并使用字段中的键值创建数组 x ,$4该字段是您想要的哈希值。接下来,我们读取第二个文件file2.txt设置FS,并检查字段值是否$1不作为数组中的键存在x,如果不存在,我们将其打印出来。
评论中提出的更惯用的说法可能是:

awk 'NR == FNR { x[$4] = 1; next; } !($1 in x)' FS="/" file1.txt FS="," file2.txt

答案3

为了GNU sed

sed -z 's%.*/\([^/]*\)/index.html\n%\1\\|%g;s%^%/%;s%\\|$%/d%' file1.csv |
sed -f - file2.csv

在哪里第一的 sed以 sed-command-format 生成哈希列表,/12ab09f46\|a77b3ff22\|..../d并将其传输到下一个 sed-script 从输入中读取上述命令,因此-f -选项。
与相同grep

grep -oP '[^/]*(?=/index.html$)' file1.csv | grep -Fvf - file2.csv

或者没有 perl 表达式:

grep -o '[^/]*/index.html$' file1.csv | 
grep -o '^[^/]*' | 
grep -Fvf - file2.csv

甚至更好:

cut -d/ -f4 file1.csv | grep -Fvf - file2.csv

答案4

我刚刚尝试了以下一种衬里,它似乎可以完成这项工作:

 for i in `cat file1.txt  | awk -F"/" '{print $4}'`; do echo "\n $i" ; sed -ri "/^$i,/d" file2.csv ; done

请先更换-里-关于来测试它。-关于进行一次试运行,如果一切正常,您可以运行它-里

相关内容