2012-09-20 38 views
1

過去幾周我花了很多時間在這裏發佈。我終於認爲我與學習bash的關係更加密切,但是我的代碼有一個問題,我不能爲我的生活弄清楚爲什麼它不會運行。我可以在終端中運行每一行,並返回一個結果,但由於某種原因,當我指出它運行時,它什麼都不會做。我得到一個語法錯誤:意外的詞(期待「做」)。bash將某些文件名打印爲文本

#!/bin/bash 

image="/Home/Desktop/epubs/images" 

for f in $(ls "$image"*.jpg); do 
    fsize=$(stat --printf= '%s' "$f"); 
    if [ "$fsize" -eq "40318" ]; then 
     echo "$(basename $f)" >> results.txt 
    fi 
done 

我錯過了什麼?

+2

你'ls'命令被作爲一個榮耀的回聲 - 假設它在所有工作,這它可能不會在'「$ image」'和'* .jpg'之間沒有'/'。只需在'$ image「/ *。jpg中輸入'f'; do'。而且,'--printf ='和''%s''之間會有一個額外的空間,這會破壞你的'stat'命令。 –

+1

@sean解釋你的意思請 –

+1

@CuriousGeorge你已經在StackOverflow上提出了5個其他問題,並且從未將其中一個答覆標記爲答案。 –

回答

0

您的循環中缺失值的列表來遍歷:

image="/Home/Desktop/epubs/images" 
for f in $(ls "$image"*.jpg); do 

因爲$image不以/結尾,您的ls命令將擴展爲

for f in $(ls /Home/Desktop/epubs/images*.jpg); do 

這可能導致

for f in ; do 

導致語法錯誤。最簡單的解決方法是

for f in $(ls "$image"/*.jpg); do 

,但你應該採取建議在其他的答案,跳過ls

for f in "$image"/*.jpg; do 
0

以下是我將如何做到這一點。

#!/bin/bash -e 

image="/Home/Desktop/epubs/images" 

(cd "$image" 
for f in *.jpg; do 
    let fsize=$(stat -c %s "$f") 
    if ((fsize == 40318)); then 
    echo "$f" 
    fi 
done) >results.txt 

-e意味着該腳本將退出,如果有什麼差錯(無法cd進入該目錄,例如)。當你對這種行爲感到滿意時,可以節省很多錯誤檢查。

圓括號表示cd命令位於子外殼中;周圍的腳本(包括重定向到results.txt)仍然在你開始任何目錄。

現在,我們在目錄中,我們可以隨便找*.jpg,沒有目錄前綴,並且不需要調用basename上任何東西。

使用let((==))對待大小值爲數字,而不是字符串,所以在方式,我們將不會絆倒任何wonkiness stat選擇格式化值。

我們只是將整個循環的輸出重定向到結果文件中,而不是每次都追加;它更有效率。如果您想要保留results.txt中的現有內容,則只需將>更改回>>,但將其留在整個循環中仍比在每次迭代中打開文件並將其附加到該文件效率更高。

+0

當我做CD桌面/ epubs我按enter鍵。路徑是正確的,我嘗試在上面的腳本sh test.sh。我返回三個錯誤。兩個是:找不到:debug.sh:另一個是debug.sh 6:debug.sh:語法錯誤:單詞意外)期待「做」)。該消息也顯示在我上面的舊腳本中。 –

+0

'sh'和'bash'是兩個不同的shell(即使它們是相同的程序)。這個腳本必須用bash運行,而不是sh。 –

+0

我的歉意我還是這個新手。你指的是如何在終端中運行.sh文件?由於./filename與sh filename.sh相關? –

1

問題可能出現在結尾。確保你的腳本文件有unix行結尾,而不是Windows。

另外,不要迭代ls的輸出。用匹配右殼:

出現
for f in "$file"/*.jpg ; do 
相關問題