编辑2:对于那些有相同问题的人,请务必阅读已接受答案的评论,因为他们更深入地了解如何正确使用该命令。一旦完成后我将发布最终脚本,并自行解释正在发生的事情。
我正在尝试编写一个简单的bash函数来清除终端屏幕,然后执行多个ls
命令以不同的颜色显示当前目录的不同内容类型。
我已经设法用Python编写了一些相同的东西,但它有一些很大的缺点(具体来说,文件名中特殊字符的行为在Cygwin上是“iffy”,并且让它适合于它是一件很痛苦的事情。屏幕)。我希望它看起来像这样:
*非dotfiles为绿色(出于隐私原因,未在屏幕截图中包含它们)。
我已设法列出隐藏目录和可见目录,但文件给我带来麻烦。使用ls
获取我尝试的所有文件的每种方法都使用-l
参数,或类似find
或grep
,所有这些都将文件输出到一列(不是我想要的)。
是否可以使用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.
}
仅列出当前目录中的点文件
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 .*
使用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_CWD
和WIN_CWD
在那里,因为Cygwin路径与Windows路径不同,我喜欢两者。 sed
命令用“/”替换Windows“\”以便于复制+粘贴。
这就是问题的答案开始的地方。 DOTDIRS
,DIRS
,DOTFILES
和FILES
变量将获得列表。
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
目录的输出。
最后的说明:
它感觉比我的Python脚本略慢,但它不会错误地使用文件名中的特殊字符,它将始终尊重终端的窗口大小,因为这就是ls
所做的。我认为“缓慢”可能是因为4个xargs ls
操作不能同时打印,而python一次打印所有内容。我可以忍受它1-2秒vs 0.5-1秒。