如何通过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
。