我想创建一个bash脚本来列出用户通过输入提供的目录中的所有目录,或者列出当前目录中的所有目录(没有输入)。
这是我迄今为止所拥有的,但当我执行它时,我遇到了两个问题。
1)脚本完全忽略了我的输入。该文件位于我的桌面上,但是当我输入" home"作为输入,脚本只打印桌面的目录(当前目录)。
2)目录打印在各自的行(打算)上,但它将文件夹名称中的每个单词视为自己的文件夹。即打印为:
this
folder
这是我到目前为止的代码:
#!/bin/bash
echo -n "Enter a directory to load files: "
read d
if [ $d="" ]; #if input is blank, assume d = current directory
then d=${PWD##*/}
for i in $(ls -d */);
do echo ${i%%/};
done
else #otherwise, print sub-directories of given directory
for i in $(ls -d */);
do echo ${i%%/};
done
fi
另外在你的回复中,请解释你的回答,因为我对bash很新。
感谢您的光临,感谢您的光临。
编辑:感谢John1024的回答,我想出了以下内容:#!/bin/bash
echo -n "Enter a directory to load files: "
IFS= read d
ls -1 -d "${d:-.}"/*/
它完成了我需要的一切。非常感谢!
答案 0 :(得分:3)
我相信这个脚本可以实现你想要的:
#!/bin/sh
ls -1 -d "${1:-.}"/*/
用法示例:
$ bash ./script.sh /usr/X11R6
/usr/X11R6/bin
/usr/X11R6/man
说明:
-1
告诉ls在单独的行上打印每个文件/目录
-d
告诉ls
按名称而不是内容列出目录
如果有一个或${1:-.}
(这意味着当前目录),那么shell将.
作为脚本的第一个参数。
上面的脚本在每个目录名的末尾显示/
。如果您不想要,我们可以使用sed
从输出中删除尾部斜杠:
#!/bin/sh
ls -1d ${1:-.}/*/ | sed 's|/$||'
从您的脚本开始,可以进行一些简化:
#!/bin/bash
echo -n "Enter a directory to load files: "
IFS= read d
d=${d:-$PWD}
for i in "$d"/*/
do
echo ${i%%/}
done
注意:
IFS= read d
在将输入分配给d
之前,通常会删除前导和尾随空格。但是,通过将IFS
设置为空值,将保留前导和尾随空格。因此,即使在用户指定名称以空格开头或结尾的目录的病态奇怪情况下,这也会起作用。
如果用户输入反斜杠,shell将尝试将其作为转义处理。如果您不喜欢,请使用IFS= read -r d
,反斜杠将被视为普通字符,而不是转义。
d=${d:-$PWD}
如果用户提供了d
的值,则会保持不变。如果他没有,则将其分配给$PWD
。
for i in "$d"/*/
这将循环遍历$d
的每个子目录,并将正确处理带有空格,制表符或任何其他奇怪字符的子目录名称。
相比之下,请考虑:
for i in $(ls -d */)
在ls
执行此处后,shell会将输出拆分为单个单词。这被称为"单词分裂"这就是为什么应该避免这种形式的for
循环。
请注意for i in "$d"/*/
中的双引号。它们可以防止$d
上的单词拆分。