Shell-Script

如何使用 find 和 awk 在 tcsh shell 腳本中的文件名中引用驚嘆號?

  • June 17, 2021

我有一個腳本,它在文件名中搜尋空格字元“ ”、驚嘆號“ !”和美元符號“ $”,並用下劃線“ _”替換每個字元。但是,它根本不處理帶有驚嘆號的文件名。在目前文件夾和所有子文件夾中搜尋要重命名的文件,直到一定深度(這裡不是很相關)。文件夾名稱也應該以相同的方式更改,這就是深度交錯的原因。

這是所需的重命名方案:

This is cool!.txt     -->    This_is_cool_.txt
Thank$.log            -->    Thank_.log
Foo 1/Bar 2/a.txt     -->    Foo_1/Bar_2/a.txt

這是腳本:

#!/bin/tcsh -f
 
foreach n ( 1 2 3 4 5 6 7 8 )
   find . -mindepth $n -maxdepth $n -name '*[ $\!]*' | fgrep -v \" | \
   awk '{printf "mv -i -- \"%s\" \"%s\"\n", gensub("!","\\\\\!","g",$0), gensub(" ","_","g",gensub("\\$","\\\\$","g",gensub("!","\\\\\!","g",$0)))}' | tcsh -cf
end 

我已經改變了\兩個驚嘆號之前的反斜杠 ’ ’ 的數量,但沒有效果。錯誤消息可能如下所示(偶數個反斜杠):

awk: cmd. line:1: warning: escape sequence `\!' treated as plain `!'

或者shell腳本(顯然)打開一個互動式shell?!有時什麼也沒有發生(我想當第一個參數中有太多反斜杠mv並且找不到文件時)。

PS:如您所見,我排除了帶有雙引號 ’ "’ 的文件,因為我也無法讓它們工作。如果您也可以建議如何處理這些問題,那就更好了!

mv直接呼叫而不是在其中合成命令awk並將其通過管道傳輸到 shell會容易得多

#!/bin/bash
#
find -mindepth 1 -maxdepth 8 -type f -name '*[ !$]*' -execdir
   bash -c 'for f in "$@"; do echo mv -- "$f" "${f//[ !$]/_}"; done' _ {} +

此版本重命名文件但不重命名目錄(如問題中所述)。如果您實際上也打算重命名目錄,請使用此變體,

find -mindepth 1 -maxdepth 8 -depth -name '*[ !$]*' -execdir
   bash -c 'for f in "$@"; do echo mv -- "$f" "${f//[ !$]/_}"; done' _ {} +

在這兩種情況下echo,當您滿意命令將執行您期望的操作時刪除。用於mv -i互動式重命名。中的下劃線bash -c '...' _ {}成為子shell 中執行的程式碼的“名稱”。它被映射到$0並將用於報告程式碼錯誤(如果有的話),所以你可以放在bash那裡甚至subshell- 它只是一個標籤。

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