我最近注意到来自 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
在三个文件中搜索:
food
、shopping
和list.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
正确的。
- 这是可笑的不切实际。
即使这样也失败了
mygrep -e cat -e dog -e fish file1 file2 file3 file4
因为它有超过九个参数!而且,虽然这种情况看起来不太可能发生,但同样的问题也会发生
mygrep bird *
如果当前目录中有超过八个(非隐藏)文件。
那么,该怎么办,该怎么办?
长话短说
如果你看进去重击(1)
在下面特殊参数,您会看到它$@
扩展到位置参数列表,从 1 开始。当扩展发生在双引号内时,每个参数都会扩展为一个单独的单词。也就是说,"$@"
相当于"$1"
"$2"
……(如上面的长脚本中所实现的,但不限于前九个)。因此,编写脚本来包装(即充当前端)某些命令(就像别名一样)的方法是
#!/bin/sh
grep --color=always "$@"