Awk

避免在 awk 腳本中使用 ls 的空格和撇號問題

  • January 3, 2021

我在兩個(本地)設備中有許多相同的文件,碰巧我只在一個設備(A)中重命名了一些文件。我找到了以下方法來根據設備 A 中的新名稱重命名另一個設備 (B) 中的相同文件,這樣最後我的文件和名稱文件都相同,無需刪除或複制任何內容,而只是重命名

事實上,我從 Hai Vu 那裡找到了一個有趣的答案第二個答案)。

該腳本有效,但有兩個問題

  1. 文件名中帶有空格:名稱被空格截斷。和
  2. 文件名中帶有apos (')

腳本 (rename-identical-files.awk) 是

/^total/ {next} # Skip the first line (which contains the total, of ls -l)

{
   if (name[$5] == "") {
   name[$5] = $NF
   print "# File of size", $5, "should be named", $NF
} else {
   printf "mv '%s' '%s'\n", $NF, name[$5]
}
}

它是從命令行呼叫的(在目標文件夾中):

awk -f ~/rename-identical-files.awk <(ls -l /model-folder-path) <(ls -l) | sh 

問題似乎是ls命令,它(至少)對文件名中的空格和其他字元有限制。

我應該寫什麼程式碼來避免空格(和撇號)問題?

的,沒有簡單的方法來解析ls可靠的輸出。

在這裡,您可以zsh改用:

#! /bin/zsh -
zmodload zsh/stat || exit
typeset -A size_to_name
model_folder=${1?}

for f in $model_folder/*(ND.); do
 stat -LA size +size -- $f &&
   size_to_name[$size]=$f:t &&
   print -r "# File of size $size should be named ${(q)f:t}"
done

for f in *(ND.); do
 stat -LA size +size -- $f &&
   (($+size_to_name[$size])) &&
   [[ $f != $size_to_name[$size] ]] &&
   print -r mv -i -- ${(qq)f} ${(qq)size_to_name[$size]}
done

(執行為that-script /model-folder-path

無論文件名可能包含哪些字元或非字元,哪個應該可以正常工作。

sh一旦你驗證它是正確的,管道到。請注意,我們不檢查兩個文件具有相同大小的情況。在這種情況下,將選擇詞法順序中的最後一個(如果a並且z兩者在 model_folder 中的大小為 42,那麼任何大小為 42 的文件都將重命名為z目前文件夾中的文件(儘管-i這會讓您有機會避免用第二))。

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