2013-11-23 36 views
1

我有一組帶有給定後綴的文件。例如,我有一組pdf文件,後綴爲.pdf。我想獲取沒有使用子字符串擴展後綴的文件的名稱。陣列上的Bash子串擴展

對於一個單一的文件,我可以使用:

file="test.pdf" 
echo ${file:0 -4} 

要執行此操作的所有文件,我現在嘗試:

files=($(ls *.pdf)) 
ff=("${files[@]:0: -4}") 
echo ${ff[@]} 

我現在得到一個錯誤,指出substring expression < 0 ..

(我想避免使用for迴路)

回答

5

使用parameter expansions刪除.pdf部分,像這樣:

shopt -s nullglob 
files=(*.pdf) 
echo "${files[@]%.pdf}" 

shopt -s nullglob使用水珠時,始終是一個好主意:它將使水珠擴大到什麼,如果沒有匹配。

"${files[@]%.pdf}"將展開爲一個陣列,並刪除所有尾部.pdf。你可以,如果你願意把這個在另一個數組像這樣:

files_noext=("${files[@]%.pdf}") 

這一切是100%安全的關於文件名(空格,換行等)有趣的符號,除了echo一部分文件命名爲-n.pdf-e.pdf-E.pdf ...但echo只是出於演示目的。你的files=($(ls *.pdf))真的很糟! 千萬不要分析ls的輸出。


回答您的評論:substring擴展不能在數組的每個字段上工作。從上面鏈接的參考手冊採取:

${parameter:offset}

${parameter:offset:length}

如果offset計算結果爲數字小於零,則該值被用作從parameter值的末端偏移。如果length的計算結果爲小於零的數字,並且parameter不是@而不是索引或關聯數組,則它被解釋爲從parameter的值的末尾開始的偏移量,而不是一定數量的字符,擴展是字符在兩個偏移量之間。如果parameter@,則結果是length位置參數以偏移量開始。 如果parameter是下標爲@*的索引陣列名稱,則結果爲以${parameter[offset]}開頭的length陣列成員。相對於大於指定數組的最大索引值的偏移量,採用負偏移量。應用於關聯數組的子字符串擴展會產生未定義的結果。

因此,例如,,

$ array=(zero one two three four five six seven eight) 
$ echo "${array[@]:3:2}" 
three four 
$ 
+0

謝謝!完美的作品:) –

+0

這是否意味着子串擴展不適用於數組? (我也嘗試'回聲「$ {files [@]:0:-3}」'它不起作用) –

+1

@HåkonHægland編輯回答你的問題。 –