使用 Grep -o 或 Sed/Awk 从字符串中间抓取片段

使用 Grep -o 或 Sed/Awk 从字符串中间抓取片段

我正在观察日志流量,发现各种图像搜索引擎(尤其是 Bing)经常被滥用。

示例网址:

http://www.bing.com/images/search?q=dagger+genesis+solo&view=detailv2&&&id=C65E811DFE01FB11258D2EB4F516F3DD8F09049C&selectedIndex=4&ccid=ffC0NVO8&simid=608046582336849763&thid=JN.XnLfF7qiZGwjJzTCR6f7ZQ&mode=overlay

我想拉出搜索本身,“匕首起源独奏”。

我可以

grep -o '=*' 

但这留下了 = 符号和搜索后面的所有内容。

我想抓取“search?q=”和最后一个单词末尾的第一个“&”之间的所有内容,前面有一个“+”。

我可以使用 awk 或 cut 以非常长且复杂的方式到达那里,以尽可能多地剥离字符串,然后使用指定的字段分隔符将每个单词放入其自己的列中,然后仅打印这些列。但即使该方法也不一致,因为搜索可以是任意长度并且几乎包括任何字符。

我认为有一个更简单的方法。有想法吗?

我的最终目标是剥离搜索查询并将它们整理成唯一的条目。

答案1

如果您的系统grep支持 PCRE 模式,您可以使用环顾四周(零长度断言)选择字符之间 search?q=&

grep -Po '(?<=search\?q=).+?(?=&)'

在两者之间使用非贪婪修饰符?会使匹配在第一个 处停止&

答案2

你可以做

sed 's/^.*search?q=\([^&]*\)&.*/\1/' file

search?q=其作用是在 the和 the之间进行非贪婪匹配&

哪个输出

dagger+genesis+solo

如果你想+用空格替换符号,

sed 's/^.*search?q=\([^&]*\)&.*/\1/;s/+/ /g' file

哪个输出

dagger genesis solo

答案3

sed

sed 's/\([^=&]*.\)\{2\}&.*/\1/' <<""
http://www.bing.com/images/search?q=dagger+genesis+solo&view=detailv2&&&id=C65E811DFE01FB11258D2EB4F516F3DD8F09049C&selectedIndex=4&ccid=ffC0NVO8&simid=

当为反向引用匹配指定出现次数时,sed应仅引用指定的匹配。所以在上面的例子中引用只返回

dagger+genesis+solo

答案4

使用 grep 后瞻和前瞻断言:

grep -oP "\=\K.*(?=\&view)"

这里,

\K          ==>  zero-width look-behind assertion
(?=\&view)  ==>  zero-width look-ahead assertion

因此,仅打印\=&viewie之间的部分。.*

相关内容