为什么用管道命令“ l | grep“ 1”是否得到错误的结果?


13

如图所示,我l通常将文件保存在当前文件夹中。然后我想获取带有编号的文件1,所以我使用pipegrep

但是为什么222文件显示出来?那是什么1;34m

$ l
./ ../ 1 11 2 22
$ l | grep "1"
1;34m./ 1;32m../ 1 11 2 22

更新资料

我已经lzshrc文件中为命令添加了别名。

 alias lsp="ls"
 alias ll='ls -alF'
 alias la='ls -A'
 alias l='ls -CF'
 alias ls="ls -alh --color"

这是type命令的结果:

>$ type ls
ls is an alias for ls -alh --color

> $ type l
l is an alias for ls -CF

4
请不要发布文字的屏幕截图。在此处复制文本并应用代码格式。
muru

@muru我想你想问的是post输出type -a l
WinEunuuchs2Unix

@ WinEunuuchs2Unix啊,是的。
muru

@Lee请问您发布type ls命令的输出吗?您是否ls以任何方式修改了别名?
Sergiy Kolodyazhnyy

@Serg已更新。

Answers:


27

首先,您要尝试做的事l| grep <filename>很糟糕。不要这样 这就是为什么。

l 命令实际上是 ls -CF

$ type -a l
l is aliased to `ls -CF'

在Ubuntu的默认情况下bashls是的别名ls --color=auto。正如钢手在评论中指出的,--color=auto应该关闭着色。在您的具体情况下,您有alias ls="ls -alh --color"and alias l="ls -CF",基本上就是ls -alh --color -CF。开关的这种特定组合仍然通过管道发送彩色输出。例如:

$ ls -alh --color -CF ~/TESTDIR | cat -A                                                                                 
^[[0m^[[01;34m.^[[0m/  ^[[01;34m..^[[0m/  1.txt  2.txt  3.txt  out.txt$

注意...目录如何具有相同的转义序列。

这是什么意思呢

这意味着l将根据文件类型输出彩色的文件列表。问题是着色是通过使用转义序列发生的。就是这样1:34m-它们是特定颜色的转义序列。

主要问题在于,解析ls通常会导致脚本输出错误和灾难,原因仅仅是因为ls允许使用转义序列(如先前所述)和其他特殊字符。有关更多信息,请参见本文:http : //mywiki.wooledge.org/ParsingLs

您应该做什么:

使用find命令:

bash-4.3$ ls
1.txt  2.txt  3.txt  out.txt
bash-4.3$ find . -maxdepth 1 -iname "*1*"
./1.txt

您可以使用shell glob和现代测试[[命令执行以下操作:

bash-4.3$ for file in * ;do if [[ "$file" =~ "1"  ]] ;then echo "$file" ;fi ; done
1.txt

或者也许使用python,它的文件名处理能力比bash单独的要好得多

bash-4.3$ python -c 'import os;print [f for f in os.listdir(".") if "1" in f ]'
['1.txt']

如果不需要处理的输出,则只需进行ls简单的globing ls即可完成这项工作。(请记住,这仅用于查看文件列表,而不用于将其传递到另一个程序来处理输出文本)

bash-4.3$ ls *1*
1.txt

2
我认为,如果也指定了输出,则只会在管道中对其进行着色--color=always-作为别名的一部分lls自身的先前别名(替换默认值alias ls='ls --color=auto')。
steeldriver

@steeldriver好点了,但这不是lsbash的默认值吗?type ls给我,这是别名ls --color=auto
Sergiy Kolodyazhnyy 16-12-28

1
是的,这是默认设置-但auto会在管道AFAIK中关闭颜色。要查看ANSI颜色序列,必须将其更改为--color=always,或者使用ls别名或l别名
steeldriver

哦,我明白你的意思。真奇怪
Sergiy Kolodyazhnyy

@steeldriver因此,我要求OP发布他的别名,显然,它们具有的别名ls --color不会阻止着色(我自己也测试过)。相应地更新了我的答案
Sergiy Kolodyazhnyy,2016年

6

lls命令设置为别名。

当您运行它们时,通过grep "1"(使用|)通过管道显示输出,1显示的每个屏幕行1均以红色显示。

由于文件名...222在同一屏幕上线出现,他们是通过输出grep作为很好,但没有出现在红这表明grep匹配。

:34m是不正确绘制颜色转义序列。根据您修改后的问题的输出结果type -a ltype -a它可以在我的系统中复制。请注意,您应该将别名从更改--color--color=auto

颜色输出

彩色ls


这些1:34m东西不是腐败,它们是用于为文本着色的转义序列。看到我对此的回答;)
Sergiy Kolodyazhnyy

@Serg谢谢。我已经根据带有别名的OP修订问题进行了修订。
WinEunuuchs2Unix

1

在您的试用版中,您调用的是ls别名,因此1;34m是由着色引起的,以及类似的噪音,由于管道|在同一行上接收到所有这些噪声,因此grep匹配该行中的文件1并因此打印该行。这就是您在屏幕上看到的。

当您执行此类操作时,最好返回到系统命令,每行显示1个结果。

要消除别名,只需键入\ls,然后使用该选项-1即可打印以换行符分隔的结果。

$ \ls -1 | grep "1"
1
11

注意:反斜杠方法适用于每个命令,\command仅调用非锯齿系统命令。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.