Shell-Script

為什麼我的文件夾名稱會變成這樣,我該如何使用腳本來解決這個問題?

  • September 1, 2019

抱歉,如果這在其他地方有答案,我不知道如何搜尋我的問題。

我在 redhat linux HPC 伺服器上執行了一些模擬,而我用於處理文件夾結構以保存輸出的程式碼有一個不幸的錯誤。我創建文件夾的 matlab 程式碼是:

folder = [sp.saveLocation, 'run_', sp.run_number, '/'];

其中sp.run_number是一個整數。我忘記將其轉換為字元串,但由於某種原因執行mkdir(folder);(在 matlab 中)仍然成功。事實上,模擬執行順利,數據被保存到匹配的目錄中。

現在,當查詢/列印文件夾結構時,我會遇到以下情況:

  • 當我嘗試選項卡自動完成時:run_ run_^A/ run_^B/ run_^C/ run_^D/ run_^E/ run_^F/ run_^G/ run_^H/ run_^I/
  • 當我使用ls: run_ run_? run_? run_? run_? run_? run_? run_? run_? run_? run_?
  • 當我使用 rsync 傳輸到我的 mac 時,--progress選項顯示:run_\#003/等(我假設)與填充為三位數字的整數匹配的sp.run_number數字,所以第 10 次執行是run_\#010/
  • 當我在 finder 中查看文件夾時,我看到run_ run_ run_ run_ run_ run_ run_ run_ run_ run_?
  • 查看這個問題並使用ls | LC_ALL=C sed -n l我得到的命令:
run_$
run_\001$
run_\002$
run_\003$
run_\004$
run_\005$
run_\006$
run_\a$
run_\b$
run_\t$
run_$

我無法cd使用這些表示中的任何一種進入文件夾。

我有數千個這樣的文件夾,所以我需要用一個腳本來解決這個問題。這些選項中哪個是文件夾的正確表示?如何以程式方式引用這些文件夾,以便使用 bash 腳本以正確格式的名稱重命名它們?我猜為了好奇,這到底是怎麼發生的?

您可以使用 perlrename實用程序(又名prenamefile-rename)重命名目錄。

**注意:**不要與renamefromutil-linux或任何其他版本混淆。

rename -n 's/([[:cntrl:]])/ord($1)/eg' run_*/

這使用 perl 的ord()函式將文件名中的每個控製字元替換為該字元的序號。例如^A變成 1,^B變成 2,等等。

-n選項是進行試執行以顯示如果您允許它rename **會做什麼。**刪除它(或將其替換-v為詳細輸出)以實際重命名。

操作中的e修飾符s/LHS/RHS/eg導致 perl 將 RHS(替換)作為 perl 程式碼執行,並且$1是來自 LHS 的匹配數據(控製字元)。

如果您想在文件名中使用零填充數字,您可以ord()sprintf(). 例如

$ rename -n 's/([[:cntrl:]])/sprintf("%02i",ord($1))/eg' run_*/ | sed -n l
rename(run_\001, run_01)$
rename(run_\002, run_02)$
rename(run_\003, run_03)$
rename(run_\004, run_04)$
rename(run_\005, run_05)$
rename(run_\006, run_06)$
rename(run_\a, run_07)$
rename(run_\b, run_08)$
rename(run_\t, run_09)$

當且僅當 sp.run_number您的 matlab 腳本在 0..26 範圍內時,上述範例才有效(因此它在目錄名稱中產生了控製字元)。

要處理任何 1 字節字元(即從 0..255 開始),您可以使用:

rename -n 's/run_(.)/sprintf("run_%03i",ord($1))/e' run_*/

如果sp.run_number可能 > 255,則必須使用 perl 的unpack()函式而不是ord(). 我不確切知道 matlab 如何在字元串中輸出未轉換的 int,因此您必須進行試驗。詳情請參閱perldoc -f unpack

例如,以下將解壓縮 8 位和 16 位無符號值並將它們零填充到 5 位寬:

rename -n 's/run_(.*)/sprintf("run_%05i",unpack("SC",$1))/e' run_*/

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