2014-07-09 37 views
0

我需要從文件名中提取2個東西 - 擴展名和數字。shell腳本迭代拋出目錄和分割文件名

我有一個文件夾「/ var/www/html/MyFolder /」,這個文件夾包含更多的文件夾,並在每個文件夾中存儲一些文件。 該文件具有以下結構:「a_X_mytest.jpg」或「a_X_mytest.png」。 「a_」已修復,並且在每個文件夾中都是相同的,我需要「X」和文件擴展名。

我的劇本是這樣的:

#!/bin/bash 
for dir in /var/www/html/MyFolder/*/ 
do 
    dir=${dir%*/} 
    find "/var/www/html/MyFolder/${dir##*/}/a_*.*" -maxdepth 1 -mindepth 1 -type f 
done 

這只是從我的腳本開始。

有一個在我的腳本錯誤:

find: `/var/www/html/MyFolder/first/a_*.*': No such file or directory 
find: `/var/www/html/MyFolder/sec/a_*.*': No such file or directory 
find: `/var/www/html/MyFolder/test/a_*.*': No such file or directory 

有誰知道哪裏的錯誤是什麼? 下一步,當上面的行正在工作時,將拆分找到的文件並獲取這兩個部分。

要拆分,我會用這個:

arrFIRST=(${IN//_/ }) 
echo ${arrFIRST[1]} 
arrEXT=(${IN//./ }) 
echo ${arrEXT[1]} 

任何人可以幫助我與我的問題嗎?

+0

爲什麼你在找到之前有for循環? – Sobrique

回答

1

我不知道所需要的複雜性,但也許你想要的是

find /var/www/html/MyFolder/ -mindepth 2 -maxdepth 2 -type f -name 'a_*.*' 

這樣:

while IFS= read -r FILE; do 
    # Do something with "$FILE"... 
done < <(exec find /var/www/html/MyFolder/ -mindepth 2 -maxdepth 2 -type f -name 'a_*.*') 

或者

readarray -t FILES < <(exec find /var/www/html/MyFolder/ -mindepth 2 -maxdepth 2 -type f -name 'a_*.*') 
for FILE in "${FILES[@]}"; do 
    # Do something with "$FILE"... 
done 
+0

我也建議'-exec'找到值得一看。 – Sobrique

+0

使用find/var/www/html/MyFolder/-mindepth 2 -maxdepth 2 -type f -name'a _ *。*'我得到正確的信息。但是,當我執行while循環時,我得到這個異常:語法錯誤附近的意想不到的令牌'(' – user3699189

+0

我真的很好奇:在過程替換中使用'exec'有什麼優勢? – mklement0

2

TL;博士:

您的腳本可以簡化爲以下幾點:

for file in /var/www/html/MyFolder/*/a_*.*; do 
    [[ -f $file ]] || continue 
    [[ "${file##*/}" =~ _(.*)_.*\.(.*)$ ]] && 
    x=${BASH_REMATCH[1]} ext=${BASH_REMATCH[2]} 
    echo "$x" 
    echo "$ext" 
done 
  • 一個單一的水珠(文件名模式,通配符模式)是你的情況足夠了,因爲水珠可以有多個通配符跨越水平等級/var/www/html/MyFolder/*/a_*.*在文件夾/var/www/html/MyFolder的(*/)的任何立即子文件夾中找到匹配a_*.*的文件。
    您只需要find即可匹配位於不同級別的子文件(但您可能還需要它以滿足更復雜的匹配需求)。
  • [[ -f $file ]] || break確保只考慮文件,並且如果找到NO匹配,也會有效地退出循環。
  • [[ ... =~ ... ]]使用bash的正則表達式匹配運算符=~從每個匹配文件的文件名部分(${file##*/})中提取感興趣的令牌。
  • 正則表達式匹配的結果存儲在保留數組變量"${BASH_REMATCH}"中,第一個元素包含第一個加括號的子表達式((...) - 也稱爲捕獲組)捕獲的內容,依此類推。

    • 或者,你也可以使用read與數組匹配的文件名解析成其組件:

      IFS='_.' read -ra tokens <<<"${file##*/}" 
      x="${tokens[0]}" 
      ext="${tokens[@]: -1}" 
      

至於爲什麼你試過沒」 t work

  • find不支持水珠參數,所以它解釋"/var/www/html/MyFolder/${dir##*/}/a_*.*"字面上
  • 此外,你必須從模式來尋找在根文件夾的子樹的任何級別分開根文件夾爲您搜索:
    • 根文件夾變成了文件名參數
    • 通過-name-iname(對於不區分大小寫的匹配)選項傳遞(總是引用)文件名模式
    • Ergo:find "/var/www/html/MyFolder/${dir##*/}" -name 'a_*.*' ...,類似於@konsolebox' answer