简体   繁体   English

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

[英]Display Only Files And Dotfiles In The Default “ls” Command Format?

EDIT 2: For those with the same question, please be sure to read the comments on the accepted answer, as they go more in depth about how to properly use the command. 编辑2:对于那些有相同问题的人,请确保阅读已接受答案的注释,因为它们会更深入地介绍如何正确使用该命令。 I will post the final script once it is done with my own explanation of what is going on. 一旦完成,我将发布最终脚本,并自己解释发生的情况。

I'm trying to write a simple bash function that clears the terminal screen, then performs multiple ls commands to show the different content types of the current directory in different colors. 我正在尝试编写一个简单的bash函数,该函数可清除终端屏幕,然后执行多个ls命令以不同的颜色显示当前目录的不同内容类型。

I've managed to write something in Python which kind of does the same thing, but it has some big drawbacks (specifically, the behavior for special characters in filenames is "iffy" on Cygwin, and it's a pain to make it fit properly on the screen). 我已经设法用Python编写了可以做相同事情的东西,但是它有一些很大的缺点(特别是,文件名中特殊字符的行为在Cygwin上是“ iffy”的,要使其正确地适合在Cygwin上是很痛苦的屏幕)。 I want it to look something like this: 我希望它看起来像这样:

Python范例

*With non-dotfiles in green (haven't include them in the screenshot for privacy reasons). *非点文件为绿色(出于隐私原因,未将其包含在屏幕截图中)。

I've managed to list both hidden directories and visible directories, but the files are giving me trouble. 我设法列出了隐藏目录和可见目录,但是文件给我带来了麻烦。 Every method of using ls to get all files I've tried uses the -l argument, or something like find or grep , all of which output the files in a single column (not what I want). 使用ls获取我尝试过的所有文件的每种方法都使用-l参数,或者诸如findgrep类的东西,所有这些方法都将文件输出在单个列中(不是我想要的)。

Is it possible to use the ls command (or something else) to output only the files or dotfiles of a directory while keeping ls 's default output format? 是否可以使用ls命令(或其他命令)仅输出目录的文件或点文件,同时保持ls的默认输出格式?

EDIT 1: Here's what the script currently looks like (not much yet, but some people want to see it) 编辑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.
}

to list only the dot files in the current directory 只列出当前目录中的点文件

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

to list only the other files 仅列出其他文件

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

For non-hidden files and directories, try 对于非隐藏的文件和目录,请尝试

ls -d *

For hidden files and directories, use 对于隐藏的文件和目录,请使用

ls -d .*

Using the answer provided by matzeri , I managed to get a nice start. 使用matzeri提供答案 ,我设法有了一个不错的开始。 That answer is still accepted, because it answered the question that I asked. 该答案仍被接受,因为它回答了我提出的问题。 Here's the current version of the script, which I've turned into a function for easy access. 这是脚本的当前版本,我已将其转换为易于访问的功能。 I'm gonna go through it and explain some things that needed to be modified from the answer to give me the result I wanted, but didn't specifically ask for. 我将仔细研究一下,并解释一些需要修改的内容,以便为我提供想要的结果,但没有特别要求。

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
}

Firstly, I wrapped the whole thing with stty to stop the user from messing-up the output with keyboard inputs. 首先,我用stty包裹了整个内容,以防止用户使用键盘输入弄乱输出。

Then, I create booleans that will allow the ls outputs at the end to be performed with a very minimal delay between them ( if [ bool ] rather than checking the status of a list). 然后,我创建一个布尔值,该布尔值将允许在最后执行ls输出,并且使它们之间的延迟最小( if [ bool ]而不是检查列表的状态)。

The color variables are simply used by the tput command, which lets you change the color of the terminal's text. 颜色变量仅由tput命令使用,它使您可以更改终端文本的颜色。

Note: Some of the color values might be off, that's because I had issues with my Cygwin theme (currently using Nord ), and these values look like their names on my setup. 注意:某些颜色值可能会关闭,这是因为我的Cygwin主题存在问题(当前使用Nord ),并且这些值看起来像它们在我的设置中的名称。 Your mileage may vary. 你的旅费可能会改变。

To fellow Cygwin users: I've had a few issues with tput not working when it would've worked on an actual Linux machine. 对于Cygwin的其他用户:当在实际的Linux机器上可以使用tput时,我遇到了一些问题。 If you're having trouble with tput consider defining the LS_COLORS (which can be formatted to accept RGB values), and setting the CLICOLOR variable to true, then exporting both. 如果您无法与tput考虑定义了LS_COLORS (可格式化接受RGB值),以及设置CLICOLOR变量设置为true,则出口两者。 This can replace the tput command, although you now might want to store the initial value of both, and you have to export the LS_COLORS variable constantly. 尽管您现在可能想要存储两者的初始值,并且必须不断导出LS_COLORS变量,但这可以代替tput命令。

The CYG_CWD and WIN_CWD are there because Cygwin paths aren't the same as Windows paths, and I like having both. CYG_CWDWIN_CWD之所以存在,是因为Cygwin路径与Windows路径不同,我喜欢两者兼有。 The sed command replaces Windows' "\\" with "/" for easy copy+paste. sed命令将Windows的“ \\”替换为“ /”,以便于复制和粘贴。

This is where the answer to the question starts. 这是问题答案的起点。 The DOTDIRS , DIRS , DOTFILES , and FILES variables will get lists. DOTDIRSDIRSDOTFILES ,并FILES变量将得到名单。

The ls command already allows us to filter just directories and directories starting with . ls命令已经允许我们仅过滤目录和以开头的目录. , via the ls -Ad */ and the ls -Ad *./ commands. ,通过ls -Ad */ls -Ad *./命令。 ls ignores files starting with . ls忽略以开头的文件. , unless specified (like I do), ending with / searches for directories, and the -d parameter makes it name directories instead of showing us what's in them. ,除非指定(像我一样),否则以/结尾搜索目录,并且-d参数将其命名为目录,而不是向我们显示目录中的内容。

As for dotfiles and regular files, ls doesn't really let us get them, because you can't specify a character which defines a file like you can with / for directories. 至于dotfile和常规文件, ls并不能真正让我们获取它们,因为您不能像使用/表示目录那样指定一个字符来定义文件。 Instead, we can use the find . -maxdepth -type f 相反,我们可以使用find . -maxdepth -type f find . -maxdepth -type f with the appropriate use of the -name or -not -name arguments to filter our files. find . -maxdepth -type f ,并适当使用-name-not -name参数来过滤文件。 There is an issue, however: the command will prefix the results with ./ . 但是,存在一个问题:该命令将在结果前添加./ So .bashrc becomes ./.bashrc . 因此.bashrc成为./.bashrc I don't want that. 我不要 The output is thus piped to the sed command, which substitutes the first two characters for nothing (effectively removing them). 因此,输出将通过管道传递给sed命令,该命令将前两个字符替换为空(有效地将其删除)。

From here, we simply determine which list has elements, set the appropriate boolean values to ensure quick ls outputs at the end, print the legend, all the while changing the colors the terminal uses with the tput command. 从这里,我们简单地确定哪个列表具有元素,设置适当的布尔值以确保在最后快速输出ls ,打印图例,同时通过tput命令更改终端使用的颜色。

Eventually, the ls_list function is called. 最终, ls_list函数被调用。 If the given boolean is true, it performs the echo "$2" | xargs -d '\\n' ls -d 如果给定的布尔值为true,则执行echo "$2" | xargs -d '\\n' ls -d echo "$2" | xargs -d '\\n' ls -d command. echo "$2" | xargs -d '\\n' ls -d命令。 Essentially, it echoes the list of items found, which is piped into the xargs -d '\\n' command. 本质上,它回显找到的项目列表,该列表通过管道传递到xargs -d '\\n'命令中。 xargs allows us to pass the values piped to it as parameters for the ls command. xargs允许我们传递传递给它的值作为ls命令的参数。 The -d '\\n' arguments changes the separator from spaces to newlines, because some names might have spaces in them. -d '\\n'参数将分隔符从空格更改为换行符,因为某些名称中可能包含空格。 What ls does, when you give it filenames, is simply prints them with the regular ls output format (which is exactly what I want). ls功能,当您给它提供文件名时,仅使用常规ls输出格式(正是我想要的)输出它们。 I added the -d parameter so that is names directories instead of showing their contents, since I'm using that function for all my lists. 我添加了-d参数,以便命名目录而不显示目录内容,因为我对所有列表都使用了该函数。

Finally, reset whatever tput is with sgr0 and re-enable keyboard inputs with stty ! 最后,使用sgr0重置任何tput并使用stty重新启用键盘输入!

This is what the output looks like for my /home directory. 这是我的/home目录的输出结果。

在此处输入图片说明

Final notes: 最后说明:

It feels slightly slower than my Python script, but it won't bug-out with special characters in filenames and it will always respect the terminal's window size, since that's what ls does. 它的感觉比我的Python脚本慢一些,但是不会用文件名中的特殊字符进行调试,并且始终会尊重终端的窗口大小,因为ls这样做的。 I think the "slowness" might be because the 4 xargs ls operations don't print at the same time, while the python one printed everything at once. 我认为“缓慢”可能是因为4个xargs ls操作不能同时打印,而python一个可以一次打印所有内容。 I can live with it being 1-2 seconds vs 0.5-1 second. 我可以忍受1-2秒vs 0.5-1秒。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM