从文件中过滤唯一参数

Ema*_*mad 5 awk grep

我的文件包含网址和参数,如下所示

https://example.com/endpoint/?param1=123&param2=1212
https://example.com/endpoint/?param3=123&param1=98989
https://example.com/endpoint/endpoint3/?param2=123
https://example.com/endpoint/endpoint2/?param1=123
https://example.com/endpoint/endpoint2/
https://example.com/endpoint/endpoint5/"//i.example.com/00/s/Nzk5WDEwMjQ=/z/47IAAOSwBu5hXIKF
Run Code Online (Sandbox Code Playgroud)

我需要仅过滤具有唯一参数的网址所需的输出

http://example.com/endpoint/?param1=123&param2=1212
https://example.com/endpoint/?param3=123&param1=98989
https://example.com/endpoint/endpoint3/?param2=123
Run Code Online (Sandbox Code Playgroud)

我设法用 grep 只过滤带有参数的 url grep -E '(\?[a-zA-Z0-9]{1,9}\=)'

但我需要同时过滤参数,所以我尝试使用 awk 和相同的正则表达式,但它给出了错误

awk '{sub(\?[a-zA-Z0-9]{1,9}\=)} !seen[$0]++'
Run Code Online (Sandbox Code Playgroud)

更新

我很抱歉编辑所需的输出,但是当我尝试脚本时,我发现我的文件中的大量碳水化合物也需要过滤。我尝试了@James Brown 进行了一些编辑,看起来不错,直到最后一行,不幸的是它没有过滤它

awk -F '?|&' '$2&&!a[$2]++'
Run Code Online (Sandbox Code Playgroud)

为了更清楚为什么该输出对我有好处,它选择了第一行,因为它至少有 param1 第二行,因为它至少有 param3 3 行,因为它至少有 param2 这里的比较方法是选择唯一参数无论它&是否与其他字符连接

Rav*_*h13 5

编辑:当查询字符串中存在?&时,以下解决方案可能会有所帮助,并且我们希望考虑使用它们来删除重复项。

awk '
/\?/{
  match($0,/\?[^&]*/)
  val=substr($0,RSTART,RLENGTH)
  match($0,/&.*/)
  if(!seen[val]++ && !seen[substr($0,RSTART,RLENGTH)]++){
    print
  }
}' Input_file
Run Code Online (Sandbox Code Playgroud)

第二个解决方案:(&当我们在查询字符串中没有参数时,以下解决方案可能会有所帮助awk程序。

awk 'match($0,/\?.*$/) && !seen[substr($0,RSTART,RLENGTH)]++' Input_file
Run Code Online (Sandbox Code Playgroud)

或上面可以缩短为如下:(根据埃德先生的建议):

awk 's=index($0,"?") && !seen[substr($0,s)]++' Input_file
Run Code Online (Sandbox Code Playgroud)

解释:简单的解释是,使用match函数awk匹配从?到 到行尾的所有值。然后向其添加 AND 条件,以确保我们仅从所有行中的所有匹配值中获取唯一值。


Jam*_*own 5

要求更改后的编辑版本:

$ awk -F? '{                   # ? as field delimiter
    split($2,b,/&/)            # split at & to get whats between ? and &
    if(b[1]!=""&&!a[b[1]]++)   # no ? means no $2
        print
}' file
Run Code Online (Sandbox Code Playgroud)

输出符合预期。原来的答案是:

简短的一个:

$ awk -F? '$2&&!a[$2]++' file
Run Code Online (Sandbox Code Playgroud)

解释:在?( -F?) 处分割记录,如果有第二个字段 ( $2) 且 ( ) 到目前为止,通过计算数组( )&&中参数的实例,它是唯一的,则将其输出。 a!a[$2]++