2010-10-25 58 views
26

快速背景:猛砸for循環上的目錄

$ ls src 
file1 file2 dir1 dir2 dir3 

腳本:

#!/bin/bash 

for i in src/* ; do 
    if [ -d "$i" ]; then 
    echo "$i" 
    fi 
done 

輸出:

src/dir1 
src/dir2 
src/dir3 

不過,我希望它改爲:

dir1 
dir2 
dir3 

現在我意識到我可以sed/awk輸出來刪除「src /」,但我很想知道是否有更好的方法來解決這個問題。也許使用find + while-loop代替。

回答

16

做到這一點,而不是爲echo行:

echo $(basename "$i") 
+0

我看你已經更新了您的文章閱讀*基名*而不是*目錄名稱* 叮,叮,叮正確! :D 謝謝,我會接受你的回答 – BassKozz 2010-10-25 03:16:05

+0

2天前從O'Rielly的書中學到了這塊金塊。如果我多年前知道它,可以節省我幾小時的時間。 – Synesso 2010-10-25 03:16:57

3

使用basename爲:

if [ -d "$i" ]; then 
    basename "$i" 
fi 
10

無需分叉外部進程:

echo "${i##*/}" 

,使用「刪除最長的匹配前綴「parameter expansion*/是該模式,因此它將刪除從字符串開頭到包括最後一個斜槓在內的所有內容。如果$i的值沒有斜線,則與"$i"相同。

此特定參數擴展爲specified in POSIX,並且是原始Bourne shell的遺留部分。它在所有類似Bourne外殼支持(SH破折號KSH慶典的zsh等)。許多功能豐富的shell(例如ksh,bashzsh)具有其他擴展,可以在不涉及外部進程的情況下處理更多的擴展。

8

如果您在腳本開始時執行cd,則應在腳本退出時恢復它。

#!/bin/bash 

cd src 
for i in * ; do 
    if [ -d "$i" ]; then 
    echo "$i" 
    fi 
done 
+2

它應該......但是如果使用'.'或'source'命令調用腳本,它不會。而是使用'pushd'和'popd'。 – Benoit 2010-10-25 11:27:11