2015-04-03 19 views
0

我有一個目錄,其中填充了由用戶上傳的PDFS,並且沒有意識到需要遵循某些命名約定來獲取文件可以再次下載。要解決這個問題,我需要運行一個bash腳本或命令,它會遞歸地遍歷子目錄,並刪除壞字符並重命名文件。BASH Linux - 如何通過echo將查找結果傳遞到mv目標

我以爲我已經想通了,但唉,我被困在一個部分。一旦我運行我的命令(見下文),我會得到一系列錯誤,顯示它找到這些文件,但移動的參數列表(目標)沒有被正確設置。如何將文件名傳遞給子命令?

find . -name '*.pdf' -or -name '*.PDF' -execdir mv -v '{}' `echo {} | tr ' ' '_' | tr -d '[{}(),\!]' | tr -d "\'" | tr '[A-Z]' '[a-z]' | sed 's/_-_/_/g'`\; 

我知道我的問題是echo {}的事情,但我不知道如何獲取find中找到的文件名。第一個替代作品,回聲一個沒有。

在此先感謝!

+0

由於在反引號內的位被評估並且代替到命令行中,所以'find'甚至開始之前失敗。你可能想看看「重命名」,而不是... – twalberg 2015-04-03 19:32:50

回答

2

ShellCheck有益指出的三個問題與你的命令:

  1. -execdir-or

  2. \;ignores everything已經是a separate argument

  3. `..`expand once發現運行之前,不是每個文件找到。

此外,

  • 的{}在tr是interpretted被發現
  • tr爭論不應該讓他們

各地[]佔所有這一切:

find . \(-name '*.pdf' -or -name '*.PDF' \) \ 
    -execdir sh -c 'mv -v "$1" "$(echo "$1" | tr " " "_" | tr -d "{()},\!'\''" | tr "A-Z" "a-z" | sed "s/_-_/_/g")"' _ {} \; 
+0

這工作完美。謝謝! – MediaGiantDesign 2015-04-03 19:59:46

-2

管一個命令到另一個像這樣:

command1 | command2 
0

這不起作用,因爲在執行find命令之前,你的命令替換(由反引號分隔)已經完成,因此{}尚不可用。我建議通過拉出換人一個循環,遍歷find的結果重組你的命令:

find . -print0 -name '*.pdf' -or -name '*.PDF' | 
while read -d $'\0' -r name ; do 
    pushd $(dirname "$name") &>/dev/null 
    newname=$(tr ' ' '_' <<<"$name" | 
       tr -d '[{}(),\!]' | 
       tr -d "\'" | 
       tr '[A-Z]' '[a-z]' | 
       sed 's/_-_/_/g') 
    mv "$name" "$newname" 
    popd &>/dev/null 
done 

在這個例子中find命令使用的print0選項與\0字符分隔其結果。指示循環頭部中的read忽略轉義序列(-r)並使用\0字符作爲分隔符(-d)。 pushdpopd用於模擬find-execdir您在原始命令中的行爲。

相關問題