2016-09-09 61 views
0

我想添加前綴不在當前目錄.sh文件和所有子目錄中的所有文件,使用findbash文件。Linux中,重命名慶典「沒有這樣的文件或目錄」錯誤

的問題是,我得到一個錯誤:

mv: cannot move './test.txt' to 'PRE_./test.txt': No such file or directory 

我的一行是:

find -type f ! -name "*.sh" -exec sh -c 'mv "{}" PRE_"{}"' _ {} \; 

我試圖xargsrename,太:

find -type f ! -name "*.sh" -print0 | xargs -0 rename 's/(.*)$/PRE_$1/' 

但我得到了同樣的錯誤。 有什麼問題? 在此先感謝!

+3

'不能移動'./test.txt'到'PRE _。/ test.txt'似乎是一個非常明確的信息 - 看看你想給的新名字這是你想要的嗎?您在整個路徑的前綴,而不僅僅是文件名。 –

+0

只在當前目錄中,或者也在當前目錄的所有子目錄中? – cxw

+0

看看http://unix.stackexchange.com/questions/199301/find-files-based-on-name-and-moving-them-with-renaming-simultaneously –

回答

1
find -type f ! -name "*.sh" -exec rename -n 's|.*/\K|PRE_|' {} + 
  • .*/在文件名匹配高達最後/通過使用\K回顧後
  • ,我們才能避免在這種情況下,需要捕獲組的

雷莫ve -n選項rename一旦顯示正確的重命名

+0

謝謝你是我需要的 – user3365834

1

find.路徑返回一路文件,所以每個find結果與./開始時,你開始在當前目錄搜索。因此,您的新文件名是PRE_./test.txt,這是test.txt在一個名爲PRE_.的目錄中。由於沒有名爲PRE_.的目錄,因此mv無法將test.txt移動到該目錄中,因此會顯示您看到的錯誤消息。當啓用extglob

shopt -s extglob 
for f in !(*.sh) ; do [[ -d "$f" ]] || mv "$f" "PRE_$f" ; done 

感謝this answer!(pattern)結構在bash,可供選擇:

如果你只在當前目錄重命名文件,而不是子目錄,你可以使用bash。它返回所有文件名而不是匹配pattern

對於所有子目錄中的文件,這樣,使用方法:

shopt -s extglob globstar 
for f in **/!(*.sh) ; do [[ -d "$f" ]] || mv "$f" "${f%/*}/PRE_${f##*/}" ; done 

感謝this answer爲globstar。 %##切割路徑組件並將PRE_粘貼到文件名開頭的正確位置。

編輯上述兩者中的[[ -d "$f" ]] ||都可以防止循環重命名目錄。

2

如果你不想改變子目錄,你可以使用這個文件:

find -type f ! -name "*.sh" -printf "%f\n" | xargs -r rename 's/(.*)$/PRE_$1/' 

的問題是文件名的./盈。

+0

這是工作,但不是子目錄;( – user3365834

1

最好不要直接在sh -c的參數中使用{},而是將其值作爲參數傳遞。然後,您可以像往常一樣使用參數擴展操作來修改其值。在這裏,我們將參數分成它的目錄和文件名組件,然後重新組裝它們,包括文件名前綴PRE_,作爲參數mv

script=' 
d=${1%/*} 
f=${1#$d} 
mv "$1" "$d/PRE_$f" 
' 
find -type f ! -name "*.sh" -exec sh -c "$script" _ {} \; 

(這是從原始的嘗試只是略有變化;你傳遞{}作爲參數,而不是用它來代替,你被「嵌入」的值直接進入傳遞給sh字符串)

您也可以使用-exec +表單來最小化調用sh的次數,方法是傳遞多個文件名並在shell中遍歷它們。 (這將啓動與純bash溶液@cxw建議收斂,但保持POSIX,以及bash 3.x的兼容性):

script=' 
for arg; 
d=${arg%/*} 
f=${arg#$d} 
mv "$1" "$d/PRE_$f" 
done 
' 
find -type f ! -name "*.sh" -exec sh -c "$script" _ {} + 
+0

這不會嘗試將'。/ foo/bar/bat'移動到'./PRE_foo/bar/bat'而不是'./foo/bar/PRE_bat'嗎?對我來說''f''會得到'foo/bar/bat'(當然,我可能會錯過一些東西) – cxw

+0

是的,我會解決這個問題的 – chepner

相關問題