[英]Looping over directories in Bash
我有一個關於bash如何工作的基本問題,以及一個相關的實際問題。
基本問題:假設我在一個有三個子目錄的目錄中:a,b和c。
母雞的代碼
for dir in $(ls)
do
echo $dir
done
吐出:
a b c
a b c
a b c
即, dir
始終存儲我的cwd
中所有文件/目錄的列表。 我的問題是:為什么世界會這么方便? 在我看來,讓dir
存儲每個元素更有用和直觀,即我想要輸出
a
b
c
另外,根據其中一個答案 - for dir in $(ls)
使用for dir in $(ls)
是錯誤的,但是當我for dir in $(ls -l)
使用for dir in $(ls -l)
我得到更多的abc
副本(比目錄/文件更多)在cwd)。 這是為什么?
我的第二個問題是實用的:如何在我的cwd
中以大寫cwd
W開頭的所有目錄(不是文件!)循環? 我開始了
for dir in `ls -l W*`
但這失敗了因為a)問題1和b)中的原因,因為它不排除文件。 建議表示贊賞。
永遠不要像這樣解析ls
的輸出( 為什么你不應該解析ls(1)的輸出 )。
另外,你的語法錯了。 你不是指()
,你的意思是$()
。
話雖這么說,要循環使用W開頭的目錄(或者使用find
命令,具體取決於你的場景):
for path in /my/path/W*; do
[ -d "${path}" ] || continue # if not a directory, skip
dirname="$(basename "${path}")"
do_stuff
done
至於你從邪惡的ls循環得到的輸出,它應該看起來不那樣。 這是預期的輸出,並說明了為什么你不想首先使用ls:
$ find
.
./c
./a
./foo bar
./b
$ type ls
ls is hashed (/bin/ls)
$ for x in $(ls); do echo "${x}"; done
a
b
c
foo
bar
這應該工作:
shopt -s nullglob # empty directory will return empty list
for dir in ./*/;do
echo "$dir" # dir is directory only because of the / after *
done
要在子目錄中遞歸,請使用globstar
:
shopt -s globstar nullglob
for dir in ./**/;do
echo "$dir" # dir is directory only because of the / after **
done
您可以@AdrianFrühwirths'的方法是遞歸通過使用子目錄globstar
太:
shopt -s globstar
for dir in ./**;do
[[ ! -d $dir ]] && continue # if not directory then skip
echo "$dir"
done
globstar
如果設置,則文件名擴展上下文中使用的模式“**”將匹配所有文件以及零個或多個目錄和子目錄。 如果模式后跟'/',則只有目錄和子目錄匹配。
了nullglob
如果設置,Bash允許不匹配任何文件的文件名模式擴展為空字符串,而不是自己。
嗯,你知道你所看到的並不是你所期待的。 您看到的輸出不是來自echo命令,而是來自dir命令。
請嘗試以下方法:
ls -1 | while read line; do
if [-d "$line" ] ; then
echo $line
fi
done
for files in $(ls) ; do
if [-d "$files" ] ; then
echo $files
fi
done
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.