這個 sed-縮網址程式何時會爆炸? - Linux
By Quintina
at 2020-11-06T22:41
at 2020-11-06T22:41
Table of Contents
其實不一定要全部擠在同一行。
看你好像對 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&hl=en_US&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'
: # 哇-- 這行那麼長不知道會不會壞掉....
: #
: # 1604555294 更新, 上面那一行到 FreeBSD 就燒了, 先斷成兩行吧 (lantw44)
: # sed 's|^\(http[s]\{0,1\}\):.*[/vd]\{0,1\}[0-9vd][/=]\([0-9a-zA-Z_-]\{11\}\).*$|\1://youtu.be/\2\
: #|' | tr -s '\n'
: # 1604671459 找了 awk 幫忙來確保 one & only one newline
: sed 's|^\(http[s]\{0,1\}\):.*[/vd]\{0,1\}[0-9vd][/=]\([0-9a-zA-Z_-]\{11\}\).*$|\1://youtu.be/\2|' | awk 1
: }
: if [ -t 0 ] # priority: stdin > "$1" > X-clipboard
: then
: # echo "$HOME" | grep -q termux && XGET="termux-clipboard-get" || XGET="xsel"
: # [ "$1" ] && echo "$1" | youtu || $XGET | youtu
: # 1604570722 還是改一下吧, 以上兩行是錯的, A && B || C 不是 if-then-else
: # (contributors: lantw44 rickieyang bitlife)
: # if echo "$HOME" | grep -q termux
: # then
: # XGET="termux-clipboard-get"
: # else
: # XGET="xsel"
: # fi
: #
: # if [ "$1" ]
: # then
: # echo "$1" | youtu
: # else
: # $XGET | youtu
: # fi
: # 1604671459 讓它在 Mac 上也會動 (rickieyang)
: if [ "$1" ]
: then
: echo "$1" | youtu
: else # termux > Mac > X11
: XGET="xsel"
: uname | grep -q "Darwin" && XGET="pbpaste"
: echo "$HOME" | grep -q "termux" && XGET="termux-clipboard-get"
: $XGET | youtu
: fi
: else
: youtu
: fi
--
我喜歡怕冷的女生
因為在冬天我可以一直抱著她
我喜歡貪吃的女生
因為我可以餵她吃東西
我喜歡愛睡的女生
因為看著她的睡臉我感到幸福
--
看你好像對 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&hl=en_US&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'
: # 哇-- 這行那麼長不知道會不會壞掉....
: #
: # 1604555294 更新, 上面那一行到 FreeBSD 就燒了, 先斷成兩行吧 (lantw44)
: # sed 's|^\(http[s]\{0,1\}\):.*[/vd]\{0,1\}[0-9vd][/=]\([0-9a-zA-Z_-]\{11\}\).*$|\1://youtu.be/\2\
: #|' | tr -s '\n'
: # 1604671459 找了 awk 幫忙來確保 one & only one newline
: sed 's|^\(http[s]\{0,1\}\):.*[/vd]\{0,1\}[0-9vd][/=]\([0-9a-zA-Z_-]\{11\}\).*$|\1://youtu.be/\2|' | awk 1
: }
: if [ -t 0 ] # priority: stdin > "$1" > X-clipboard
: then
: # echo "$HOME" | grep -q termux && XGET="termux-clipboard-get" || XGET="xsel"
: # [ "$1" ] && echo "$1" | youtu || $XGET | youtu
: # 1604570722 還是改一下吧, 以上兩行是錯的, A && B || C 不是 if-then-else
: # (contributors: lantw44 rickieyang bitlife)
: # if echo "$HOME" | grep -q termux
: # then
: # XGET="termux-clipboard-get"
: # else
: # XGET="xsel"
: # fi
: #
: # if [ "$1" ]
: # then
: # echo "$1" | youtu
: # else
: # $XGET | youtu
: # fi
: # 1604671459 讓它在 Mac 上也會動 (rickieyang)
: if [ "$1" ]
: then
: echo "$1" | youtu
: else # termux > Mac > X11
: XGET="xsel"
: uname | grep -q "Darwin" && XGET="pbpaste"
: echo "$HOME" | grep -q "termux" && XGET="termux-clipboard-get"
: $XGET | youtu
: fi
: else
: youtu
: fi
--
我喜歡怕冷的女生
因為在冬天我可以一直抱著她
我喜歡貪吃的女生
因為我可以餵她吃東西
我喜歡愛睡的女生
因為看著她的睡臉我感到幸福
--
Tags:
Linux
All Comments
By Tracy
at 2020-11-08T11:15
at 2020-11-08T11:15
By Heather
at 2020-11-09T23:50
at 2020-11-09T23:50
By Zenobia
at 2020-11-11T12:25
at 2020-11-11T12:25
Related Posts
這個 sed-縮網址程式何時會爆炸?
By Ida
at 2020-11-04T06:52
at 2020-11-04T06:52
求推薦Linux gcc c語言的指令的書
By Caitlin
at 2020-11-02T23:46
at 2020-11-02T23:46
apt-get 載入libraries出錯
By Noah
at 2020-11-02T22:54
at 2020-11-02T22:54
Top指令內的Mem in_d是什麼意思?
By Candice
at 2020-11-02T16:43
at 2020-11-02T16:43
kernel 5.9 with nvidia driver
By Ingrid
at 2020-10-31T07:13
at 2020-10-31T07:13