2013-05-13 31 views
1

在Linux上,命令:

for f in *; do cp "$f" "$f"_copy; done

預期因爲「_copy」字符串的文件擴展名後附加不起作用,成爲foo.png_copy而不是foo_copy.png。我如何解決它?我可以切分字符串嗎?

回答

2

使用basename,傳遞給它的第二參數:

for f in *; do 
    cp "$f" "$(basename "$f" .png)_copy.png" 
done 

根據basename(1)

概要

basename [後綴]

說明

basename實用程序刪除[…]一個後綴,如果給定的。

+0

這很好,但有一個串片或替換功能,如果我需要它由於某種原因? – MaiaVictor 2013-05-13 04:30:10

+0

@Dokkat:您可以使用[Bash的參數擴展](https://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameter-Expansion)。不過,我並不是很熟悉,這就是爲什麼這個迴應花了這麼長時間! – icktoofay 2013-05-13 04:38:51

6
for f in *; do 
    prefix="${f%.*}" 
    suffix="${f:${#prefix}}" 
    cp "$f" "${prefix}_copy${suffix}" 
done 

這通過修剪後綴匹配查找文件名的前綴 「*」。請注意,如果文件名沒有擴展名,這將是整個文件名;如果它有多個句點,它只會刪除最後一個句點(例如,對於名爲「this.that.etc.png」的文件,它將被修剪爲「this.that.etc」)。然後根據前綴的長度(${#prefix})通過切分文件名來查找後綴;這可以按預期工作,不管是否有任何東西被移除。

警告:這將對待任何具有句號的文件名具有擴展名。例如,「file_v1.0」將被複制到「file_v1_copy.0」。

注意:如果你想要的話,你可以跳過定義$後綴,並且在copy命令中直接使用${f:${#prefix}},但我認爲這更清晰。

2

如果文件名只有一段

rename ".png" "_copy.png" *.png 

man rename 
+0

歡迎來到Stack Overflow。請儘快閱讀[常見問題]。考慮到在問題中使用'*'而不是'* .png',可能有其他文件不僅僅是PNG文件,在這種情況下,您提議的只能處理PNG文件,而不是所有的文件。你還應該知道''rename'命令有幾個不同的版本。你暗示使用一個(相對微弱的)版本;還有另一個使用Perl和Perl正則表達式的版本(所以'rename'/ .png $/_ copy.png /'* .png'可以完成你的命令所做的工作)。即便如此,+1和歡迎。 – 2013-05-17 06:58:55

+0

在當前的Ubuntu的這個正則表達式版本是標準的;你可以通過'rename.ul'來訪問那個提到的merlin:'rename.ul。 _複製。 *'。這樣所有的文件都帶有一個'。'在他們這裏得到這個'_copy.'替換。另外我想提一下的是,OP不想重命名,但要複製超出'rename'範圍的內容(帶或不帶'.ul')。 – Alfe 2013-05-17 10:41:30

+0

你是對的,但即便如此,這是一個很好的答案,並給了我另一個很好的選擇,謝謝。 – MaiaVictor 2013-05-17 19:46:36