Re: [问题] 这个 sed-缩网址程式何时会爆炸?

楼主: Gold740716 (项为之强)   2020-11-06 22:41:16
其实不一定要全部挤在同一行。
看你好像对 sed 还有爱,可以看看 sed 的语法。
我会把不同的 pattern 写成不同行,会比较好读,
也不用想要怎么把一堆 pattern 挤在同一个 regexp 里。
反正只会有一行能成功匹配执行,其它会因为不匹配就放掉了。
另外你的 (idempotent) ,是保留 protocol 而已吗?
还是希望连 querystring 其它参数也保留?
要的话可能要多写几个 pattern 去抓。
```sh
youtu() {
local vid
vid='\([0-9a-zA-Z_-]\{11\}\)'
sed "
# hold protocol to hold space
h
s|^\(https*://\).*|\1|
s|\$|youtu.be/|
x
# only one of them should match
s|.*/v/$vid\$|\1|
s|.*/v/$vid?.*|\1|
s|.*/watch?v=$vid.*|\1|
s|.*/watch?.*&v=$vid.*|\1|
s|.*/user/.*/[0-9]*/$vid\$|\1|
s|.*/user/.*/[0-9]*/$vid?.*|\1|
s|.*embed/$vid\$|\1|
s|.*embed/$vid?.*\$|\1|
# append replace result to hold space
# then move all to pattern space
H
g
# there should be a \n after Hold, so remove it
s/\n//
"
}
```
后面有个比较奇怪的写法是我用 s 把换行删掉,
因为 H 把 pattern space 加到 hold space 结尾时,
似乎会加上一个换行符,那就只好事后再删掉。
※ 引述《cuello (cuello)》之铭言:
: #!/bin/sh
: #
: # 1604436674 created for testing in Linux/PTT
: #
: # 这是个 YouTube 缩网址的 one-liner. 必须很 portable.
: # 我已测试过各种不同形状的水管 url's 例如:
: #
: # /v/<VID>
: # watch?v=<VID>
: # embed/<VID>?rel=0
: # watch?argv=xyz&v=<VID>
: # watch?v=<VID>&list=PLDB852818BF378DAC
: # watch?v=<VID>&feature=related
: # watch?argv=xyz&v=<VID>
: # watch?v=<VID>&feature=feedrec_grec_index
: # user/IngridMichaelsonVEVO#p/a/u/1/<VID>
: # v/<VID>?fs=1&amp;hl=en_US&amp;rel=0
: # watch?v=<VID>#t=0m10s
: # embed/<VID>?rel=0
: # watch?v=<VID>
: # http://youtu.be/<VID> (idempotent)
: #
: # 能不能帮忙看看还有哪些 url's 会出错, 并帮忙想办法?
: #
: # 我本来不喜欢缩网址的, 因为不知道有效期限多久...
: # 但如果我没误解的话, youtu.be 是水管自家的,
: # 而且保留了原始的影片 ID (确定都是11个字吗?).
: # 所以还可以接受.
: #
: # 解说:
: #
: # 0. 它必须尽可能 portable, 不管什么系统, 必须随抄即用
: # 谁有 Solaris, SunOS, OsX, Ultrix, AIX, ... 拜托!
: # 我只是很好奇, 它能有多广的 portability.
: #
: # 1. 请忽视与 termux 有关的东西, 那是让手机也可以用的,
: #
: # 2. youtu() 就已经是个充份的 one-liner.
: # 为了应付可能出现的杂七杂八的选项及形态
: # 我决定撷取 \1. protocol 跟 \2. video_id
: # 然后忽略掉其它可能出现的所有东西.
: #
: # 3. 为方便测试, 所以它要可以从 X-clipborad 读取,
: # 由 stdin 读取, 也可以由指令行读取.
: #
: # 4. 用了 sed(1) tr(1) grep(1) xsel(1) termux-clipboard-get(1)
: #
: # 5. 1604555294 新增, 原本的 -e 's/$/\n/' | tr -s '\n' 是为了确保
: # 行尾起码有一个 newline, 而且只有一个. 这也是为了使用上方便.
: youtu()
: {
: # sed -e 's|^\(http.\?\):.*[/vd]\{0,1\}[0-9vd][/=]\([0-9a-zA-Z_-]\{11\}\).*$|\1://youtu.be/\2|' -e 's/$/\n/' | tr -s '\n'
: # 哇
作者: holishing   2020-11-06 22:54:00
在 FreeBSD 装 gsed (X
作者: cuello (cuello)   2020-11-07 17:20:00
展开来真的比较容易维护, 我来放一起好吗?
楼主: Gold740716 (项为之强)   2020-11-07 19:45:00

Links booklink

Contact Us: admin [ a t ] ucptt.com