Regular-Expression

為什麼每當我使用完整路徑而不是目前路徑時,“重命名”的行為會有所不同?

  • January 9, 2014

好的,我正在回答一個問題,即 OP 在 Ubuntu 中有多個儲存庫,這可能會導致安裝不相關軟體時出現問題。我建議使用單個襯裡禁用 PPA,rename然後按照一系列說明進行操作。一切都很好,我只是把這個問題留下來回答……不。結果rename不符合我的預期:

sudo rename s/list/list\.disable/g /etc/apt/sources.list.d/*.list

有了這個,我希望 rename 可以查看/etc/apt/sources.list.d/任何以結尾的文件.list並將其替換.list.list.disable. 我用幾乎相同的命令得到了另一個答案,但 OP 從未給出回饋,而且我有點在沒有先測試的情況下拋出理論。所以,令我驚訝的是,OP 發現這條線有問題:

Can't rename /etc/apt/sources.list.d/iaz-battery-status-quantal.list /etc/apt/sources.list.disable.d/iaz-battery-status-quantal.list.disable: No such file or directory
Can't rename /etc/apt/sources.list.d/ubuntu-wine-ppa-quantal.list /etc/apt/sources.list.disable.d/ubuntu-wine-ppa-quantal.list.disable: No such file or directory
Can't rename /etc/apt/sources.list.d/webupd8team-java-raring.list /etc/apt/sources.list.disable.d/webupd8team-java-raring.list.disable: No such file or directory

我有一種奇怪的感覺,所以我自己測試了這個理論,並看到了相同的結果。然後,每當您遇到問題時,通常是正則表達式,不是嗎?我以多種扭曲的方式更改了正則表達式:

  • s/.list/.list.disable/g
  • s/.list/.list.disable/g
  • /list/list.disable/
  • 我不記得的其他組合

好吧,我認為正則表達式不是問題,所以我瞪著選擇器,將其更改為/etc/apt/sources.list.d/*並回收正則表達式測試。沒有喜悅。我有點沮喪touch some.list並應用我的命令

rename s/\.list/\.list\.disable/g *

答對了!現在我感覺整個人都被控制了。我修正了我的答案並繼續我的生活……不!這是不可接受的。為什麼?我查閱了手冊,令我驚訝的是它只使用了目前路徑範例。這是正常的嗎?還是只是功能沒有實現?或者我應該開始懷疑我的理論?

使用該-n參數以試rename執行模式執行,這在您想要測試模式時非常有用:

martin@martin ~ % rename -n s/list/list.disable/g /etc/apt/sources.list.d/*.list | sed 's/renamed as/\n =>/g'
[...]
/etc/apt/sources.list.d/spotify.list 
=> /etc/apt/sources.list.disable.d/spotify.list.disable
/etc/apt/sources.list.d/steam.list 
=> /etc/apt/sources.list.disable.d/steam.list.disable
[...]

這裡明顯的錯誤是模式list匹配,因此您嘗試重命名文件夾及其包含的文件。sources.**list**.d

請改用此模式:

rename -n 's/\.list$/.list.disable/' /etc/apt/sources.list.d/*.list | sed 's/renamed as/\n =>/g'
[...]
/etc/apt/sources.list.d/spotify.list 
=> /etc/apt/sources.list.d/spotify.list.disable
/etc/apt/sources.list.d/steam.list 
=> /etc/apt/sources.list.d/steam.list.disable
[...]

區別在於:

  1. .在搜尋模式中引用\.確保該點僅匹配一個真實的點,而不是任何字元(這就是正則表達式中未引用的點通常所做的)。
  2. 後面的$列表表示“字元串結尾”。它確保只有文件名末尾的“.list”匹配並被替換,而不是路徑或文件名中其他位置的“.list”。
  3. 您不需要在替換字元串中引用點;因此,“.list.disable”可以不使用反斜杠,因為.那裡不再有特殊含義。
  4. 另請注意,我在單引號中引用了正則表達式,以防止 shell 以任何方式修改它。

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