我正在观察日志流量,发现各种图像搜索引擎(尤其是 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
因此,仅打印\=
和&view
ie之间的部分。.*