仅显示默认“ls”命令格式的文件和Dotfiles?

问题描述 投票:0回答:3

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

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

我已经设法用Python编写了一些相同的东西,但它有一些很大的缺点(具体来说,文件名中特殊字符的行为在Cygwin上是“iffy”,并且让它适合于它是一件很痛苦的事情。屏幕)。我希望它看起来像这样:

Python Example

*非dotfiles为绿色(出于隐私原因,未在屏幕截图中包含它们)。

我已设法列出隐藏目录和可见目录,但文件给我带来麻烦。使用ls获取我尝试的所有文件的每种方法都使用-l参数,或类似findgrep,所有这些都将文件输出到一列(不是我想要的)。

是否可以使用ls命令(或其他)仅输出目录的文件或dotfiles,同时保持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.
}
bash cygwin ls
3个回答
1
投票

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

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

仅列出其他文件

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

0
投票

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

ls -d *

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

ls -d .*

0
投票

使用answer provided by matzeri,我设法得到一个好的开始。这个答案仍然被接受,因为它回答了我提出的问题。这是脚本的当前版本,我已将其转换为易于访问的功能。我将通过它并解释一些需要从答案中修改的东西,以便给出我想要的结果,但没有特别要求。

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() {
    # $1 - boolean - condition to print
    # $2 - list - names to 'ls'
    if $1 ; then
        echo "$2" | 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参数使它成为名称目录,而不是向我们展示它们中的内容。

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

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

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

最后,使用tput重置任何sgr0并使用stty重新启用键盘输入!

这就是我的/home目录的输出。

enter image description here

最后的说明:

它感觉比我的Python脚本略慢,但它不会错误地使用文件名中的特殊字符,它将始终尊重终端的窗口大小,因为这就是ls所做的。我认为“缓慢”可能是因为4个xargs ls操作不能同时打印,而python一次打印所有内容。我可以忍受它1-2秒vs 0.5-1秒。

© www.soinside.com 2019 - 2024. All rights reserved.