如何通过shell脚本创建显示所有目录的命令?

如何通过shell脚本创建显示所有目录的命令?,shell,directory,command,sh,command-line-arguments,Shell,Directory,Command,Sh,Command Line Arguments,我想创建一个命令,显示作为参数给定的目录中的所有目录。例如,如果我们的文件层次结构是这样的: dir1: dir2 dir3 file1 dir4: file2 dir5 然后,rep dir1的结果应显示: dir2 dir3 dir4 dir5 而rep dir1/dir4应显示: dir2 dir3 dir4 dir5 目前,我有一个shell脚本rep.sh执行以下操作: function rep(){ a

我想创建一个命令,显示作为参数给定的目录中的所有目录。例如,如果我们的文件层次结构是这样的:

dir1:
    dir2
    dir3
    file1
    dir4:
        file2
        dir5
然后,
rep dir1
的结果应显示:

dir2
dir3
dir4
dir5
rep dir1/dir4
应显示:

dir2
dir3
dir4
dir5
目前,我有一个shell脚本
rep.sh
执行以下操作:

function rep(){
    all=`ls $1`
    for each in $all
    do 
        if [ -d $each ]
        then
            echo $each
        fi
    done
}
通过
bash rep.sh
执行此脚本不会执行任何操作,我认为这是正确的,但是当我执行
rep dir1
rep dir1/dir4
时,它不会显示任何内容。我认为我的错误在于我没有正确地使用函数环境,或者我没有正确地传递参数。

您可以为此使用and

...
find "$1" -mindepth 1 -maxdepth 1 -type d -exec basename {} \;
...
选项
-mindepth 1
-maxdepth 1
可防止列出基本目录或向下进入子目录
-type d
应用过滤器,以便只列出目录和
-exec basename{}对找到的项执行
basename
basename
剥离路径,以便只打印目录名本身。

您可以为此使用and

...
find "$1" -mindepth 1 -maxdepth 1 -type d -exec basename {} \;
...
选项
-mindepth 1
-maxdepth 1
可防止列出基本目录或向下进入子目录
-type d
应用过滤器,以便只列出目录和
-exec basename{}对找到的项执行
basename
basename
剥离路径,以便只打印目录名本身。

在纯Bash中:

rep(){
对于“$1”/*/”中的目录,请执行以下操作
dir=${dir%/}
printf'%s\n'${dir##*/}
完成
}
glob
“$1”/*/
获取所有目录;然后,这两个参数展开将删除尾部斜杠和目录路径

这会忽略隐藏的目录;如果还需要这些,则必须启用
dotglob
shell选项。要保留该shell选项的设置,可以按如下方式包装函数:

rep(){
本地dg
#获取当前点全局设置
dg=$(shopt-p dotglob)
#启用点glob
shopt-s dotglob
对于“$1”/*/”中的目录,请执行以下操作
dir=${dir%/}
printf'%s\n'${dir##*/}
完成
#将dotglob设置回原来的状态
$dg
}

至于脚本不起作用的原因:分配给脚本后,请查看
all
中包含的内容

$ all=$(ls "$1")
$ declare -p all
declare -- all="dir2
dir3
dir4
file1"
(注意,我还用
$()
和双引号
$1
替换了过时的反勾号)

ls
的输出不包含目录的路径,这就是为什么
-d
测试对所有内容都返回false

使用
ls
的方式很容易出错:分词和参数扩展会使这样的脚本对于任何带有空白或shell元字符的文件名都失败(请参阅)。改用globs。

在纯Bash中:

rep(){
对于“$1”/*/”中的目录,请执行以下操作
dir=${dir%/}
printf'%s\n'${dir##*/}
完成
}
glob
“$1”/*/
获取所有目录;然后,这两个参数展开将删除尾部斜杠和目录路径

这会忽略隐藏的目录;如果还需要这些,则必须启用
dotglob
shell选项。要保留该shell选项的设置,可以按如下方式包装函数:

rep(){
本地dg
#获取当前点全局设置
dg=$(shopt-p dotglob)
#启用点glob
shopt-s dotglob
对于“$1”/*/”中的目录,请执行以下操作
dir=${dir%/}
printf'%s\n'${dir##*/}
完成
#将dotglob设置回原来的状态
$dg
}

至于脚本不起作用的原因:分配给脚本后,请查看
all
中包含的内容

$ all=$(ls "$1")
$ declare -p all
declare -- all="dir2
dir3
dir4
file1"
(注意,我还用
$()
和双引号
$1
替换了过时的反勾号)

ls
的输出不包含目录的路径,这就是为什么
-d
测试对所有内容都返回false

使用
ls
的方式很容易出错:分词和参数扩展会使这样的脚本对于任何带有空白或shell元字符的文件名都失败(请参阅)。改用globs。

三个错误:

1) 使用

all=`ls $1`
而不是

all="$1"/*
本杰明·W.指出了这一点

2) 我忘了在我的
rep.sh
文件末尾放
rep$1
。因此,该文件如下所示:

function rep(){
    all="$1"/*    
    for each in $all
    do 
        if [ -d $each ]
        then
            echo $each
        fi
    done
}

rep $1
3) 在命令行中,我需要放置
alias rep=“bash rep.sh”
,以便能够在命令行中自由使用命令
rep

三个错误:

1) 使用

all=`ls $1`
而不是

all="$1"/*
本杰明·W.指出了这一点

2) 我忘了在我的
rep.sh
文件末尾放
rep$1
。因此,该文件如下所示:

function rep(){
    all="$1"/*    
    for each in $all
    do 
        if [ -d $each ]
        then
            echo $each
        fi
    done
}

rep $1

3) 在命令行中,我需要放置
alias rep=“bash rep.sh”
,以便能够在命令行中自由使用命令
rep

尽管这可能是一个合适的答案,但我希望在我已经存在的rep.sh文件中找到错误。尽管这可能是一个合适的答案,我想在我已经存在的rep.sh文件中找到错误。这不起作用。当我执行bash rep.sh,然后执行rep dir1时,它没有显示任何内容,我还需要执行其他操作吗?@J.Schmidt您必须首先获取包含函数的文件:
。rep.sh
,然后使用函数,
rep dir1
。这不起作用。当我执行bash rep.sh,然后执行rep dir1时,它没有显示任何内容,我还需要执行其他操作吗?@J.Schmidt您必须首先获取包含函数的文件:
。rep.sh
,然后使用函数,
rep dir1