在linux中使用Bash列出带空格的目录

时间:2014-10-12 22:56:47

标签: linux bash shell

我想创建一个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:-.}"/*/

它完成了我需要的一切。非常感谢!

1 个答案:

答案 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上的单词拆分。