2009-11-21 33 views
4

您好我不習慣做事猛砸,所以我有一些問題:擊:對於文件名做

我的目標是尋找一個文件夾中的特殊文件,如果發現產生了一些其他具有相同文件名的文件,但擴展名不同。

喜歡的東西:

For Files-that-are-called-"SysBackup*.Now" 
do 
    NewFileName = ChangeFileExt(FoundFilename),BK 
    GenerateNewfile(NewFileName) 
done 

以上是當然dummycode的,我不會打擾你與我做的代碼,因爲它不:-)工作

所以我們的目標應該是:

如果文件夾包含 Sysbackup123.now和Sysbackup666.now,我將結束與文件Sysbackup123.bk和Sysbackup666.bk

感謝您的幫助

邁克爾

回答

8

相當簡單:

for a in Sysbackup*.now; 
do 
    [ -f $a ] && touch $(basename $a .now).bk ; 
done 
+0

+1。不知道「basename」的第二個參數。 – Stephan202 2009-11-21 17:22:41

+0

Bash還允許從帶*%*的字符串末尾剝離字符。你可能*應該養成引用文件名的習慣:** touch「$ {a%.now} .bk」** – NVRAM 2009-11-21 17:26:15

+0

嗯,一件事: 在Sysbackup * .now;文件中做文件 echo「 WTF?「 done 問題是,我每次運行我的腳本時,即使沒有Sysback.now文件,WTF?也會被寫入屏幕。我會猜測(我需要)該函數只運行if實際上是一個Sysbackup * .now文件 – Reiler 2009-11-21 18:11:15

1

你可以做這樣的事情:

for F in SysBackup*.Now; do 
    [ -f $F ] && touch $(echo "$F" | sed 's/Now$/BK/') 
done 

它使用echo到文件名傳遞給sed,從而改變後綴串"Now""BK"touch創建文件,如果它還不存在。新文件將爲空。測試[ -f $F ]確保只考慮文件(不包括目錄或符號鏈接)。您也可以使用find。使用basename一個例子,如證明Stephen Darlington's answer

find . -type f -iname "SysBackup*.Now" -exec sh -c "touch \$(basename '{}' .Now).BK" \; 

注意,在這兩個例子來放置引號將文件名,以確保與空格的文件名的正確處理是很重要的。

2

這是我如何與sh做到這一點:

#!/bin/sh 

for file in SysBackup*.now; do 
    if [ ! -e "$file" ]; then 
    continue 
    fi 

    base=${file##*/} 
    bk=${base%.now}.bk 

    touch $bk 
done 
+0

儘管我不相信它特別有趣,但是我使用的解決方案不會更快,因爲它不需要fork和調用'basename'? – 2009-11-25 22:37:32

2

這裏的另一種方式做替代。 Bash有一個相當於sed中的s/string1$/string2/它使用正則表達式美元符號選擇模式的結尾:

for a in Sysbackup*.Now; 
do 
    [ -f $a ] && touch "${a/%.Now/.BK}" 
done 

百分號末匹配和磅(#)開頭相匹配。

+0

您需要在第一行使用**。Now **:如果您匹配文件,它們將以**。now ** not **結尾。現在**作爲OP使用,並且如您在變量中使用的那樣模式 - 因此,您只需觸摸原始文件。 – NVRAM 2009-11-23 00:50:59

+0

哎呀,錯字,修好了,謝謝。 – 2009-11-23 00:57:41

+0

正如我所說* ghostdog74 * - 這一個原因,我通常避免*替代*模式,並使用*刪除/附加*替代:** $ {file%.Now} .BK ** - 這將永遠不會與原始文件名相同。我曾經做過這樣的事情:** grep「$ PATTERN」「$ a」>「$ {a /%。Now/.BK}」** - 因此丟失了我的所有數據。 – NVRAM 2009-11-23 06:45:03

0

這裏的另一種方式,如果你不想使用循環並測試其是否一個文件或不

find /path -maxdepth 1 -type f -name "Sysbackup*now" | while read file 
do 
    touch "${file/%.now/.bK}" 
done 
+0

不知道我喜歡用** find **來避免不匹配的問題,但無論如何。但是,在* -name *參數中需要一個點,否則會找到一個名爲** Sysbackup-before-snow **的文件,並且由於它不會以「.now」結尾,所以文件名將會保持不變,到** touch **程序。我通常會避免使用* substitute *模式,並使用* remove/append *代替:** $ {file%.now} .bk ** - 這與原始文件名永遠不會相同(至少它會附加一個「.bk」)。 – NVRAM 2009-11-23 06:40:25