是否可以为特定文件分配 ls 命令的输出颜色? 我问的原因是,对于 git 存储库,我希望跟踪的文件与未跟踪的文件具有不同的颜色。因此,具体而言,我想获取“git ls-files”的输出,并为这些文件指定某种颜色(或将名称设为粗体或其他)。
对于标准的 ls 命令来说,这非常简单。假设您想以紫色显示所有 .mp3 文件,然后运行:
$ LS_COLORS=$LS_COLORS:"*mp3=35:"
另外,请确保您的 ls 命令启用了 --color 选项。我通常使用类似的东西:
alias ls='ls --color=auto'
紫色是“35”。其他基本颜色有:
0 = default colour
1 = bold
4 = underlined
5 = flashing text
7 = reverse field
40 = black background
41 = red background
42 = green background
43 = orange background
44 = blue background
45 = purple background
46 = cyan background
47 = grey background
100 = dark grey background
101 = light red background
102 = light green background
103 = yellow background
104 = light blue background
105 = light purple background
106 = turquoise background
我也想实现与 git 目录列表完全相同的效果。
我的解决方案是在 Z shell (
add-zsh-hook chpwd git-alias
) 中添加一个钩子,当我更改目录时调用函数 git-alias
。
函数 git-alias
根据是否为 git 目录定义 ll
的功能。
function git-alias {
# Let ll depend on the current directory
if git rev-parse --git-dir > /dev/null 2>&1; then
# Make sure ll has no alias assigned
alias ll='ls' && unalias ll
function ll {
ls $@ -lF|grep --color=never -e '/$' # directories
ls $@ -lQ|grep -f <(git ls-files -cdmoi --exclude-standard)|sed -e "s/\(.*\) \"\(.*\)\"$/\1 ${fg[dgray]}\2 (ignored)$reset_color/" # ignored
ls $@ -l|grep --color=never -f <(git ls-files -c 2>/dev/null) # cached
ls $@ -lQ|grep -f <(git ls-files -m 2>/dev/null)|sed -e "s/\(.*\) \"\(.*\)\"$/\1 ${fg[blue]}✎ \2$reset_color/" # modified
ls $@ -lQ|grep -f <(git ls-files -o --exclude-standard 2>/dev/null)|sed -e "s/\(.*\) \"\(.*\)\"$/\1 ${fg[blue]}★ \2$reset_color/" # new
git ls-files -d 2>/dev/null|sed -e "s/^\(.*\)$/Deleted: ${fg[red]}✗ \1$reset_color/" # deleted
}
else
alias ll='ls -lF'
fi
}
这将返回类似以下内容:
它仍然不完美(例如,请注意文件“LICENSE”的双重输入以及文件和文件夹的固定顺序),但这是我能实现的最好的。
我想出了另一个近似解决方案:
tree | sed -f <(git ls-files | awk -F/ '{ print "s/" $NF "/\033[32m\\0\033[0m/" }')
它从 git 获取所有跟踪文件的列表,并为每个文件创建一个 sed 命令,将文件名包装在颜色转义序列中。
还有一些不足:
着色基于文件名而不是整个路径。如果不同目录中的两个文件具有相同的名称,并且一个文件被跟踪,而另一个文件没有被跟踪,则两个文件都会被着色。
实际上更糟糕,因为甚至文件名的一部分都是彩色的。如果跟踪文件
a
,则每个 a
都会被着色。这可能可以通过匹配 sed 命令中的整行来解决。
目录没有颜色(除非它们与跟踪文件同名;见上文)。这可以通过使用
--directory
的
git ls-files
标志来改进
可能更多...
我使用
tree
而不是 ls
,这使得目录问题较少出现(因为我可以查看它是否包含跟踪文件)。但是您当然可以以相同的方式使用ls
。
我还想在一个
ls -l
中列出跟踪和未跟踪的文件,就像带有颜色编码前缀的输出一样。
alias lsg="git ls-files --others --exclude-standard | sed 's/\(.*\)/printf \"\\\033[31m(*)\\\033[0m\" \
\&\& ls -l --color \1 /' | sh && git ls-files | sed 's/\(.*\)/printf \"\\\033[32m(*)\\\033[0m\" \
\&\& ls -l --color \1 /' | sh"
git ls-files --others --exclude-standard
- 列出未跟踪的文件。git ls-files
- 列出跟踪的文件。sed 's/\(.*\)/printf [...]'
部分:
printf
- 创建彩色括号星号(绿色表示已跟踪,红色表示未跟踪),不带换行符。ls -l --color \1
- 使用捕获的文件名 (\1
) 来详细列出具有常用颜色编码的文件。它几乎是完美的,只是因为它是一一列出文件,所以显示大小的列不再格式整齐。