仅显示默认 "ls" 命令格式的文件和点文件?

Display Only Files And Dotfiles In The Default "ls" Command Format?

编辑 2:对于那些有相同问题的人,请务必阅读对已接受答案的评论,因为它们更深入地介绍了如何正确使用该命令。完成后我将 post 最终脚本,并附上我自己对正在发生的事情的解释。

我正在尝试编写一个简单的 bash 函数来清除终端屏幕,然后执行多个 ls 命令以不同颜色显示当前目录的不同内容类型。

我已经设法在 Python 中写了一些东西,它做同样的事情,但它有一些很大的缺点(具体来说,文件名中特殊字符的行为在 Cygwin 上是 "iffy" , 让它在屏幕上正确显示是一件很痛苦的事情)。我希望它看起来像这样:

*非点文件为绿色(出于隐私原因未将其包含在屏幕截图中)。

我设法列出了隐藏目录和可见目录,但这些文件给我带来了麻烦。使用 ls 获取我尝试过的所有文件的每种方法都使用 -l 参数,或类似 findgrep 的东西,所有这些都在单个文件中输出文件专栏(不是我想要的)。

是否可以使用 ls 命令(或其他命令)仅输出目录的文件或点文件,同时保持 ls 的默认输出格式?

编辑 1:这是脚本当前的样子(还不多,但有些人想看)

function test() {
    clear;

    GOLD=229;
    RED=203;
    BLUE=39;
    WHITE=15;
    GREEN=121;

    # Colored legend.
    tput sgr0;
    tput setaf bold
    # echo's "-n" suppresses the new line at the end.
    tput setaf $GOLD;
    echo -n "Working Directory ";
    tput setaf $RED;
    echo -n "Hidden Directories ";
    tput setaf $BLUE;
    echo -n "Visible Directories ";
    tput setaf $WHITE;
    echo -n "Hidden Files ";
    tput setaf $GREEN;
    echo "Visible Files";

    pwd;

    ls -d .*/; # List hidden directories.
    ls -d */; # List visible directories.
    # List dotfiles.
    # List files.
}

仅列出当前目录中的点文件

find .  -maxdepth 1 -type f -name ".*" | xargs ls --color=tty

仅列出其他文件

find .  -maxdepth 1 -type f -not -name ".*" | xargs ls --color=tty

对于非隐藏文件和目录,尝试

ls -d *

对于隐藏文件和目录,使用

ls -d .*

使用 ,我成功地开始了。该答案仍然被接受,因为它回答了我提出的问题。这是脚本的当前版本,我已将其转换为函数以便于访问。我将通过它并解释一些需要从答案中修改的内容,以便为我提供我想要的结果,但没有特别要求。

c() {
    stty -echo; # Disable keyboard inputs during function.

    local HAS_DOTDIRS=false;
    local HAS_DIRS=false;
    local HAS_DOTFILES=false;
    local HAS_FILES=false;

    local BLUE=39;
    local GOLD=229;
    local GREEN=121;
    local PINK=170;
    local RED=203;
    local WHITE=15;

    local CYG_CWD=$(pwd);
    local WIN_CWD=$(cygpath -w "$(pwd)" | sed 's/\/\//g');

    local DOTDIRS=$(ls -Ad .*/); # Get directories with '.' prefix.
    local DIRS=$(ls -Ad */); # Get normal directories.
    local DOTFILES=$(find .  -maxdepth 1 -type f -name ".*" | sed 's/^..//');
    local FILES=$(find .  -maxdepth 1 -type f -not -name ".*" | sed 's/^..//');

    clear;
    tput sgr0;
    tput setaf bold;

    local LEGEND="$(tput setaf $GOLD)Cygwin Working Directory ";
    LEGEND+="$(tput setaf $PINK)Windows Working Directory ";

    if ! [ -z "$DOTDIRS" ] ; then
        HAS_DOTDIRS=true
        LEGEND+="$(tput setaf $RED)Hidden Directories ";
    fi

    if ! [ -z "$DIRS" ] ; then
        HAS_DIRS=true
        LEGEND+="$(tput setaf $BLUE)Visible Directories ";
    fi  

    if ! [ -z "$DOTFILES" ] ; then
        HAS_DOTFILES=true
        LEGEND+="$(tput setaf $WHITE)Hidden Files ";
    fi

    if ! [ -z "$FILES" ] ; then
        HAS_FILES=true
        LEGEND+="$(tput setaf $GREEN)Visible Files";
    fi

    echo $LEGEND; 
    echo "";

    echo "$(tput setaf $GOLD)$CYG_CWD";
    echo "$(tput setaf $PINK)$WIN_CWD";

    tput setaf $RED
    ls_list "$HAS_DOTDIRS" "$DOTDIRS"

    tput setaf $BLUE
    ls_list "$HAS_DIRS" "$DIRS"

    tput setaf $WHITE
    ls_list "$HAS_DOTFILES" "$DOTFILES"

    tput setaf $GREEN
    ls_list "$HAS_FILES" "$FILES"

    tput sgr0;

    stty echo; # Enable keyboard inputs after function.
}

ls_list() {
    #  - boolean - condition to print
    #  - list - names to 'ls'
    if  ; then
        echo "" | xargs -d '\n' ls -d;
    fi
}

首先,我用 stty 包裹了整个东西,以防止用户用键盘输入搞乱输出。

然后,我创建布尔值,允许最后的 ls 输出在它们之间以非常小的延迟执行(if [ bool ] 而不是检查列表的状态)。

颜色变量仅供 tput 命令使用,可让您更改终端文本的颜色。

注意: 某些颜色值可能不正确,那是因为我的 Cygwin 主题(目前使用 Nord)有问题,这些值看起来像他们的名字在我的设置上。您的里程可能会有所不同。

致 Cygwin 用户: 我遇到了一些问题,tput 在实际的 Linux 机器上可以正常工作时无法正常工作.如果您在使用 tput 时遇到问题,请考虑定义 LS_COLORS(可以格式化为接受 RGB 值),并将 CLICOLOR 变量设置为 true,然后导出两者。这可以替代 tput 命令,尽管您现在可能想要存储两者的初始值,并且您必须不断导出 LS_COLORS 变量。

CYG_CWDWIN_CWD 在那里是因为 Cygwin 路径与 Windows 路径不同,我喜欢两者兼有。 sed命令将Windows的“\”替换为“/”,方便复制+粘贴。

问题的答案从这里开始。 DOTDIRSDIRSDOTFILESFILES 变量将获得列表。

ls 命令已经允许我们通过 ls -Ad */ls -Ad *./ 命令过滤目录和以 . 开头的目录。 ls 忽略以 . 开头的文件,除非指定(像我一样),以 / 结尾的文件搜索目录,并且 -d 参数使其命名目录而不是向我们展示里面有什么。

至于点文件和常规文件,ls 并没有真正让我们得到它们,因为您不能像使用 / 用于目录那样指定定义文件的字符。相反,我们可以使用 find . -maxdepth -type f 并适当使用 -name-not -name 参数来过滤我们的文件。 但是存在一个问题: 该命令将在结果前加上 ./。所以 .bashrc 变成 ./.bashrc。我不想要那个。因此,输出通过管道传输到 sed 命令,该命令将前两个字符替换为空(有效地删除它们)。

从这里,我们只需确定哪个列表包含元素,设置适当的布尔值以确保在末尾快速 ls 输出,打印图例,同时更改终端使用的颜色 tput命令。

最终,ls_list 函数被调用。如果给定的布尔值为真,它会执行 echo "" | xargs -d '\n' ls -d 命令。本质上,它会回显找到的项目列表,该列表通过管道传输到 xargs -d '\n' 命令中。 xargs 允许我们将通过管道传递给它的值作为 ls 命令的参数传递。 -d '\n' 参数将分隔符从空格更改为换行符,因为某些名称中可能包含空格。 ls 所做的,当你给它文件名时,只是用常规的 ls 输出格式打印它们(这正是我想要的)。我添加了 -d 参数,以便命名目录而不是显示它们的内容,因为我正在为我的所有列表使用该函数。

最后,使用 sgr0 重置 tput 并使用 stty!

重新启用键盘输入

这是我的 /home 目录的输出结果。

最后的注释:

它感觉比我的 Python 脚本稍慢,但它不会因文件名中的特殊字符而出错,并且它始终会尊重终端的 window 大小,因为这就是 ls 确实如此。我认为 "slowness" 可能是因为 4 个 xargs ls 操作不会同时打印,而 python 一次打印所有内容。我可以接受 1-2 秒对 0.5-1 秒。