我确实有以下find-file
脚本:
find . -type f -iname "*$1*" -printf '%P\n' \
| GREP_COLORS="sl=0;33;49:ms=1;34;49" grep --color=always '^\|[^/]*$' \
| grep -i --color=auto "$1"
它的作用是:
- 给路径部分着色
- 对基本名称部分中的图案进行着色
问题:图案后,颜色被重置
对于基本名称部分,它可以是完全白色的,这可以解决问题(尽管我没有找到改变它的方法)。
对于路径部分,它仍然是一个问题,正如您在上面的屏幕截图中所看到的:颜色被重置,因此我们再也看不到文件路径真正结束的地方!
有针对这个的解决方法吗?
编辑 - 有3个解决方案!以下所有建议都有效,它们有轻微的差异,但它们确实回答了问题。我选择了一个突出显示所有出现的模式的选项,并且几乎是一行,但老实说选择很困难,因为它们相当相同......
编辑 - 人们希望对此进行改进:在分析之前,查找结果不会被阻塞,也就是说,输出会被逐行刷新和处理。这可能吗?
答案1
也许是这样的?
命令:
pattern='oRg'; find . -type f -iname "*$pattern*" -printf '%P\n' \
| GREP_COLORS="sl=0;33:mt=1;34" grep --color=always '[^/]*$' \
| GREP_COLORS="sl=1;34" grep --color=always -iP "$pattern(?=[^/]*$)" \
| GREP_COLORS="sl=0;33" grep -i "$pattern" --color
如果您不想突出显示,请删除最后一行图案部分dirname
。
查看grep的环境变量GREP_COLORS
部分了解详细信息。
答案2
zsh
您可以使用的内置全局运算符来完成此操作。这将有几个好处:
- 轻松解决这个问题
- 使用包含换行符的路径名
- 可以轻松地仅突出显示基本名称中的模式
- 使用通配符(在您的方法中,
find
并grep
以不同的方式解释模式) - 给你一个排序列表
- 甚至可以在非 GNU 系统上工作(
-printf
、-iname
、--color
都是非标准扩展)。
也许是这样的:
#! /bin/zsh -
pattern="(#i)${1?Please specify a pattern}"
set -o extendedglob
typeset -A find_file_color
find_file_color=(
dirname $'\e[0;33;49m'
basename $'\e[1;34;49m'
match $'\e[1;33;44m'
reset $'\e[m'
)
colorize_file() {
local file=${1-$REPLY}
case $file in
(*/*)
REPLY=$find_file_color[dirname]$file:h$find_file_color[reset]/;;
(*)
REPLY=
esac
REPLY+=$find_file_color[basename]${${file:t}//(#m)$~pattern/$find_file_color[match]$MATCH$find_file_color[basename]}$find_file_color[reset]
}
print -rC1 -- **/*$~pattern*(ND.+colorize_file)
print
请注意,它会在传递到打印之前构建整个列表并对其进行排序。因此,只有找到所有文件后,您才会开始获得一些输出。要在找到它们时打印它们(但随后我们需要放弃排序),您可以让 glob 限定符函数打印彩色文件:
#! /bin/zsh -
pattern="(#i)${1?Please specify a pattern}"
set -o extendedglob
typeset -A find_file_color
find_file_color=(
dirname $'\e[0;33;49m'
basename $'\e[1;34;49m'
match $'\e[1;33;44m'
reset $'\e[m'
)
colorize_file() {
local file=${1-$REPLY}
case $file in
(*/*)
REPLY=$find_file_color[dirname]$file:h$find_file_color[reset]/;;
(*)
REPLY=
esac
REPLY+=$find_file_color[basename]${${file:t}//(#m)$~pattern/$find_file_color[match]$MATCH$find_file_color[basename]}$find_file_color[reset]
print -r -- $REPLY
false # don't bother adding the file to the glob expansion
}
: **/*$~pattern*(ND.+colorize_file)
答案3
1)如何为文本着色的示例
# creation of 3 escape sequences
C_1=$(echo -ne "\033[30;47m" ) ;
C_2=$(echo -ne "\033[32;41m" ) ;
C_3=$(echo -ne "\033[37;44m" ) ;
C_N=$(echo -ne "\033[0m" ) ;
#simple example for using it
echo $C_1 Hello in C_1 $C_N normal ;
echo $C_2 Hello in C_2 $C_N normal ;
echo $C_3 Hello in C_3 $C_N normal ;
值的解释在这里: https://en.wikipedia.org/wiki/ANSI_escape_code#3/4_bit
在您的情况下,因为您正在寻找简单的模式,所以我只能使用一个 sed 命令。
PAT="tot" ;
find ./ -iname \*$PAT\* -printf '%P\n' | \
sed "s/^\(.*\/\)\{0,1\}\([^\/]*\)\($PAT\)\([^\/]*\)\$/${C_1}\1${C_2}\2${C_3}\3${C_N}\4/i"
\1 is the full path ending with the last /
\2 is the pattern of the filename before the pattern
\3 is the pattern
\4 is after the pattern