2017-03-31 77 views
0

好的,所以我正在嘗試編寫一個簡單的shell腳本來檢查更新或只更新所有包,包括自制軟件本身。我試圖將可執行文件名稱回顯到一個txt文件中,並在最後輸入txt文件。問題是,在我的腳本中,無論我做什麼,它總是在它創建的文本文件中包含文本文件的名稱。我該如何跳過文本文件,或者刪除包含pkg.txt的整行?請記住,它不會像刪除最後一行那樣簡單,因爲軟件包是按字母順序列出的,如果我安裝了任何以大於p的字母開頭的軟件包,它將刪除該行。如何在迭代目錄時跳過txt文件?

這是我的代碼到目前爲止。

for FILE in $HOME/.brew/bin/* ; do 
    TRIM=$(basename $FILE) 
    if [ "$FILE" != "*.txt" ] ; then 
    echo "brew upgrade \c" >> pkg.txt ; echo $TRIM >> pkg.txt 
    fi 
done 

不知道它的問題,但我目前在iTerm2運行的zsh。

+0

是您的*腳本*要使用bash或zsh中運行? (對於bash來說,很多語法都是不正確的,http://shellcheck.net/會捕獲這些語法)。也就是說,第一個開始行是以'#!/ bin/bash','#!/ usr/bin/env zsh'還是別的嗎? ('#!/ bin/sh'表示只保證POSIX sh基線)。 –

+0

...如果解釋器本身不是bash,那麼'bash'標籤不應該用在StackOverflow問題中。 –

+0

順便說一下,把'>> pkg.txt放在'done'上會更有效率,因此在整個循環中只打開一次輸出文件,而不是每次打開文件都要重新打開文件一行一行,並在寫完一行後關閉它。 –

回答

1

使用case來匹配模式。

for FILE in "$HOME"/.brew/bin/* ; do 
    TRIM=$(basename "$FILE") 
    case "$FILE" in 
    *.txt) ;; 
    *) echo "brew upgrade '$TRIM'" >> pkg.txt ;; 
    esac 
done 
+0

貫穿引用錯誤?嘖嘖。 (''$ HOME「/ .bug/bin/*'和'basename」$ FILE「'至少)。 –

+0

(理所當然,OP是否在交互式shell或shell實際解釋腳本的情況下提及zsh有點不清楚,但我假設''bash'標記意味着它只是前者。 –

+0

謝謝。雖然在實踐中,我懷疑有0美元的HOME目錄與空白。主目錄實際上總是以用戶名命名的,我不認爲用戶名中允許有空格。 – Barmar

2

它失敗,因爲[ "$FILE" != "*.txt" ]是一個文字字符串比較。

Zsh支持[[ "$FILE" != *.txt ]]以匹配模式(也支持b​​ash和ksh,對於dashsh,請使用@ Barmar的建議)。

這是在你的代碼:

#!/usr/bin/zsh 
for FILE in $HOME/.brew/bin/* ; do 
    TRIM=$(basename $FILE) 
    if [[ "$FILE" != *.txt ]] ; then 
    echo "brew upgrade \c" >> pkg.txt ; echo $TRIM >> pkg.txt 
    fi 
done 
+0

感謝您的回答,只是出於好奇,我如何在shell腳本中使用zsh only命令並讓它由zsh執行?我以前遇到過某些命令無法正常工作的問題,因爲(我認爲)它是作爲bash命令執行的。我試過'哪裏zsh'並把#!''在我的文件的頂部zsh輸出',但它沒有幫助。也嘗試過'exec/bin/zsh',但剛剛結束腳本。 –

+0

* nod * - 並且zsh作爲顯式的解釋器,那麼在主目錄或其名稱中包含空格或水平字符的「bin」文件的情況下,所有缺失的引號不再是引發錯誤的引號。 –

+0

@ElliotTregoning,如果你想確保你的腳本是用'zsh'解釋的,但不知道zsh二進制文件將在哪裏,你可以使用'#!/ usr/bin/env zsh'。 –