簡體   English   中英

循環在Bash中的目錄

[英]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

來自Bash手冊:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM