Linux

簡化子串替換列表

  • January 5, 2018

我寫了一個播放音樂的腳本。但是這些文件的名稱很奇怪。

說我有這個文件名字元串

Muzzy__Break_Away__28feat._Priority_One_29__5BMonstercat_EP_Release_5D.mp3

我想實現這個

Muzzy Break Away feat Priority One

到目前為止,我已經在 bash 中得到了這個。

file="whatever";
file=${file//_/" "};
file=${file//[0123456789ABCDEF][0123456789ABCDEF]/""};  #replaces bytes
file=${file//.extension1/""};
file=${file//.extension2/""};
file=${file//.extensionn/""}; #many more, e.g. .mp3
file=${file//word1/""};
file=${file//word2/""};
file=${file//wordn/""}; #many more, e.g. Monstrcat
file=${file//./""};
echo "$file";

有沒有辦法以相同的順序在 1 個命令中簡化此操作(區分大小寫)?

你可能會呼叫 perl:

formatted=$( perl -lpe '
       s/([0-9A-F]{2})/chr hex $1/eg;   # hex to ascii
       s/_+/ /g;                        # underscores to space
       s/\[[^]]*\]//g;                  # remove bracketed text
       s/[^[:alnum:][:blank:]]//g;      # remove non-alphanumeric,non-blank chars
   ' <<<"${file%.*}"
)
echo "$formatted"
Muzzy Break Away feat Priority One

這些_28看起來像某些字元的十六進制編碼。也許你想要類似的東西(用zsh而不是bash):

$ autoload zmv
$ zmv -n '*.mp3' '${${f//(#b)_([0-9A-F](#c2))/${(#)$((0x$match))}}//_/ }'
mv -- Muzzy__Break_Away__28feat._Priority_One_29__5BMonstercat_EP_Release_5D.mp3 Muzzy\ \ Break\ Away\ \(feat.\ Priority\ One\)\ \[Monstercat\ EP\ Release\].mp3

如果要重命名:

Muzzy__Break_Away__28feat._Priority_One_29__5BMonstercat_EP_Release_5D.mp3

Muzzy  Break Away (feat. Priority One) [Monstercat EP Release].mp3

-n(如果滿意,請刪除(用於試執行))。

如果您有文件名$file並希望顯示更好的表示形式,請使用:

set -o extendedglob # (that's on by default in zmv)
display=${${${file//(#b)_([0-9A-F](#c2))/${(#)$((0x$match))}}//_/ }:r}
  • (#b)啟動反向引用(因此$match[1]在替換中是模式中擷取的第一個字元串)
  • ${(#)var}將 的內容解釋$var為數字並擴展為具有相應程式碼點的字元
  • $var:r獲取文件名的根名(刪除副檔名)$var

引用自:https://unix.stackexchange.com/questions/414762