长话短说

长话短说

我最近注意到来自 grep 的这条消息

"grep: warning: GREP_OPTIONS is deprecated; please use an alias or script"

我收到此警告是因为 --color=always 在我的 .bashrc 文件中定义。 AFAIK 别名是不切实际的,因为我希望它在管道上工作。例如,

echo "a b c" |grep b

应该突出显示b。由于别名不起作用,因此提供的另一个选项是制作脚本。但是如何让脚本接受来自管道的输入呢?在本例中,我希望脚本附加 --color=always。

编辑:别名确实有效……编写脚本也是如此。我不知道别名方法哪里做错了。但是,在编写脚本时,请务必包含 $1 作为输入参数。

对于其他想知道如何通过管道传输到自己的脚本的人来说,在这个示例中,它通过执行以下操作对我有用:

首先将脚本放在路径中的某个位置,使其可执行,例如

# ~/.bin/testgrep
grep --color=always $1

现在使脚本可执行,例如

chmod +x ~/.bin/testgrep

现在应该可以了!

答案1

别名将起作用。我grep的别名是grep --color=auto

% which grep
grep: aliased to grep --color=auto

到 grep 的管道具有您想要的行为:

在此输入图像描述

答案2

grep(即/bin/grep)如果在没有文件名参数的情况下调用,将从标准输入中读取。因此,编写一个grep使用标准输入的输入运行的脚本很简单- 只需grep在不带文件名参数的情况下调用即可。但grep必须(至少)给予一个图案论证(或等价物)。一种极其不灵活的方法是将搜索字符串(模式)硬编码到 grep 脚本中,这在现实生活中不太可能很有用;例如,

#!/bin/sh
grep --color=always cat

可以在上下文中使用

ps | mygrep

可能没有什么其他的了。 A轻微地更灵活的脚本可能会使用环境变量作为搜索字符串:

#!/bin/sh
grep --color=always $USER

可以在上下文中使用

ps -ef | mygrep

可能没有什么其他的了。唯一合理、现实、可靠的解决方案是允许脚本用户提供搜索字符串作为命令行参数:

#!/bin/sh
grep --color=always $1

可以在上下文中使用

dmesg | mygrep TCP

并且实际上可能相当有用。

好吧,也许我应该说有些有用。这很快就会崩溃,因为您可能需要多个参数来指定搜索参数:

mygrep -i TCP                   不区分大小写的搜索;寻找传输控制协议,传输控制协议,TCP, ETC。
mygrep -v bash                  找到一切除了巴什
mygrep -e 猫 -e 狗            查找包含以下内容的每一行或者
mygrep -f 单词列表              搜索字符串位于文件中。

所以我们脚本的第二稿可能是:

#!/bin/sh
grep --color=always $1 $2 $3 $4 $5 $6 $7 $8 $9

它可以处理上述任何示例。作为额外的好处,这不需要用于读取标准输入;我们可以说

mygrep -i path .bashrc

它会运行

grep --color=always -i path .bashrc

但我们还没有完成!考虑

mygrep  "cat food"  "shopping list.txt"

将运行

grep --color=always cat food shopping list.txt

它将(尝试)cat在三个文件中搜索: foodshoppinglist.txt.好的,我们可以这样处理

#!/bin/sh
grep --color=always "$1" "$2"

#!/bin/sh
grep --color=always "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9"

不是一个好的答案;它会转动

mygrep  "cat food"  "shopping list.txt"

进入

grep --color=always  "cat food"  "shopping list.txt"  ""  ""  ""  ""  ""  "" ""

它将执行您想要的操作,但也会发出七个错误消息。

那么,该怎么办,该怎么办?等一下;我的衣柜里有一把大锤:

#!/bin/sh
if [ "$1" = "" ]
then
    printf "%s\n" "error: mygrep must be run with at least one argument."
elif [ "$2" = "" ]
then
    grep --color=always "$1"
elif [ "$3" = "" ]
then
    grep --color=always "$1" "$2"
elif [ "$4" = "" ]
then
    grep --color=always "$1" "$2" "$3"
elif [ "$5" = "" ]
then
    grep --color=always "$1" "$2" "$3" "$4"
elif [ "$6" = "" ]
then
    grep --color=always "$1" "$2" "$3" "$4" "$5"
elif [ "$7" = "" ]
then
    grep --color=always "$1" "$2" "$3" "$4" "$5" "$6"
elif [ "$8" = "" ]
then
    grep --color=always "$1" "$2" "$3" "$4" "$5" "$6" "$7"
elif [ "$9" = "" ]
then
    grep --color=always "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8"
else
    grep --color=always "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9"
fi

正确的。

  1. 这是可笑的不切实际。
  2. 即使这样也失败了

    mygrep  -e cat  -e dog  -e fish  file1  file2  file3  file4
    

    因为它有超过九个参数!而且,虽然这种情况看起来不太可能发生,但同样的问题也会发生

    mygrep  bird  *
    

    如果当前目录中有超过八个(非隐藏)文件。

那么,该怎么办,该怎么办?

长话短说

如果你看进去重击(1) 在下面特殊参数,您会看到它$@扩展到位置参数列表,从 1 开始。当扩展发生在双引号内时,每个参数都会扩展为一个单独的单词。也就是说,"$@"相当于"$1""$2"……(如上面的长脚本中所实现的,但不限于前九个)。因此,编写脚本来包装(即充当前端)某些命令(就像别名一样)的方法是

#!/bin/sh
grep --color=always "$@"

相关内容