一、缘由
一般切割提取字符串的字段,如果有规律可寻,采用awk或者cut就可以搞定。如果无规律的分隔符,就必须要用正则表达式来提取需要的数据了。
二、解决办法
使用sed时,我通常通过搜索除分隔符之外的任何东西来实现非贪婪搜索,直到分隔符为止:
echo "http://www.suon.co.uk/product/1/7/3/" | sed -n 's;\(http://[^/]*\)/.*;\1;p'
输出
http://www.suon.co.uk
这是:
- 不输出不打印
-n
- s搜索,匹配模式,替换并打印
s/<pattern>/<replace>/p
- 使用
;
搜索命令分隔符而不是/
使其更容易键入,以便s;<pattern>;<replace>;p
- 记住括号之间的匹配
\(
…\)
,以后可通过\1
,\2
… 访问 - 固定匹配
http://
- 后面在括号任何东西
[]
,[ab/]
就意味着无论是a
或b
或/
- 首先
^
是[]
中的not
,所以[^/]
是除了/
的其他字符 *
是重复前一组,[^/]*
表示重复除/
以外的字符,也意味着重复到/
就结束了。- 到目前为止,
sed -n 's;\(http://[^/]*\)
表示搜索并记住(提取),http://
后面紧跟任何字符,除了/
,记住(提取)您找到的内容 - 我们要搜索直到域的末尾,所以在下一个
/
停止,因此/
在末尾添加。另一个:sed -n 's;\(http://[^/]*\)/'
。(可以不需要) - 我们要匹配域后的其余行,因此添加
.*
- 在组1(
\1
)中记住的匹配项是域,因此将匹配的行替换为保存在组中\1
并把内容打印p
出来:sed -n 's;\(http://[^/]*\)/.*;\1;p'
三、实际例子
提取SQL语句中的某个字段(goods_sku)
SQL语句如下:
string="UPDATE \`db\`.\`purchase_mould\` SET \`update_time\`=1, \`__dropped_col_16__\`=\`2023-11-14 23:27:55\`, \`goods_id\`=\`123123123\`, \`mould_id\`=123123, \`specs_crc\`=123123, \`pid\`=123123, \`state\`=8.00, \`pusername\`=\`aaaa\`, \`protect_price\`=2, \`shop_id\`=123123, \`create_time\`=\`2023-12-02 19:37:56\`, \`game_name\`=\`火影\`, \`goods_sku\`=316123123, \`duration\`=1, \`game_id\`=560, \`mould_name\`=\`鲛肌\`, \`id\`=54916 WHERE \`update_time\`=2 AND \`__dropped_col_16__\`=\`2023-11-14 23:27:55\` AND \`goods_id\`=\`5123431\` AND \`mould_id\`=12222 AND \`specs_crc\`=123123444 AND \`pid\`=1122222 AND \`state\`=1.00 AND \`pusername\`=\`zaaaaa\` AND \`protect_price\`=2 AND \`shop_id\`=741231 AND \`create_time\`=\`2023-12-02 19:37:27\` AND \`game_name\`=\`火影\` AND \`goods_sku\`=316123 AND \`duration\`=1 AND \`game_id\`=560 AND \`mould_name\`=\`鲛肌` AND \`id\`=5123 LIMIT 1; #start 349365354 end 349365957 time 2023-12-02 19:37:56"
sed正则表达式:
echo $string |sed -n "s;.*\(\`goods_sku\`=[^ ]*\).*;\1;p
如果只具体的值,不要字段,只需要把字段移到分组括号外就行。
echo $string1 |sed -n "s;.*\`goods_sku\`=\([^ ]*\).*;\1;p"
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 lxwno.1@163.com