我正在Linux上编写bash脚本,需要遍历给定目录中的所有子目录名。如何遍历这些目录(并跳过常规文件)?

例如: 指定目录为/tmp/ 目录包括:/tmp/A、/tmp/B、/tmp/C

我想找回A B C。


当前回答

找到。-type d -maxdepth

其他回答

TL; diana:

(cd /tmp; for d in */; do echo "${d%/}"; done)

解释。

没有必要使用外部程序。您所需要的是一个外壳填充模式。为了避免之后需要删除/tmp,我在一个子shell中运行它,这可能不适合您的目的。

概括地说,Shell globbing模式:

*匹配任意次数的非空字符串。 ? 精确匹配一个字符。 […匹配括号内的字符。您还可以指定范围([a-z], [A-F0-9]等)或类([:digit:], [:alpha:]等)。 [^……匹配一个不是在大括号之间的字符。

*如果没有文件名与模式匹配,shell将原封不动地返回模式。任何不是上述之一的字符或字符串都表示其本身。


因此,模式*/将匹配任何以/结尾的文件名。文件名后面的/可以清楚地标识一个目录。

最后一点是删除后面的斜杠,这是通过变量替换${var%PATTERN}实现的,它从var中包含的字符串末尾删除最短的匹配模式,其中PATTERN是任何有效的通配符模式。因此我们写入${d%/},这意味着我们想要从d表示的字符串中删除后面的斜杠。

find . -mindepth 1 -maxdepth 1 -type d -printf "%P\n"
cd /tmp
find . -maxdepth 1 -mindepth 1 -type d -printf '%f\n'

简单解释一下:

find finds files (quite obviously) . is the current directory, which after the cd is /tmp (IMHO this is more flexible than having /tmp directly in the find command. You have only one place, the cd, to change, if you want more actions to take place in this folder) -maxdepth 1 and -mindepth 1 make sure that find only looks in the current directory and doesn't include . itself in the result -type d looks only for directories -printf '%f\n prints only the found folder's name (plus a newline) for each hit.

就是这样!

到目前为止,所有答案都使用find,这里有一个只有外壳的答案。在您的情况下不需要外部工具:

for dir in /tmp/*/     # list directories in the form "/tmp/dirname/"
do
    dir=${dir%*/}      # remove the trailing "/"
    echo "${dir##*/}"    # print everything after the final "/"
done

简而言之,将find的结果放入一个数组并迭代该数组并执行您想要的操作。不是最快的,而是更有条理的思考。

#!/bin/bash

cd /tmp

declare -a results=(`find -type d`)

#Iterate the results

for path in ${results[@]}
do
    echo "Your path is $path"
    #Do something with the path..

    if [[ $path =~ "/A" ]]; then
        echo $path | awk -F / '{print $NF}'
        #prints A

    elif [[ $path =~ "/B" ]]; then
        echo $path | awk -F / '{print $NF}'
        #Prints B

    elif [[ $path =~ "/C" ]]; then
        echo $path | awk -F / '{print $NF}'
        #Prints C
    fi
done

这可以简化为查找-type d | grep "/A" | awk -F / '{print $NF}'打印A

find -type d | grep "/B" | awk -F / '{print $NF}'打印B find -type d | grep "/C" | awk -F / '{print $NF}'打印C