我有这个函数(在我的 ~/.zshrc 中定义):
function graliases
{
if [[ "$#*" -lt 1 ]]
then
echo "Usage: graliases <regex>"
else
echo "$*"
grep -E '*"$*"*' ~/.dotfiles/zsh/aliases.zsh
fi
}
~/.dotfiles/zsh/aliases.zsh
这个函数应该做的是使用参数提供的正则表达式搜索文件。对于正则表达式,附加和前置两个星号,这将使查找结果独立于行中的位置。如果我使用普通的 grep,我的想法是有效的:
$ grep -E '*git rebase*' ~/.dotfiles/zsh/aliases.zsh
alias gr='git rebase'
alias gra='git rebase --abort'
alias grc='git rebase --continue'
alias gri='git rebase --interactive'
alias grs='git rebase --skip'
$ grep -E '*ls -la*' ~/.dotfiles/zsh/aliases.zsh
alias lnew='ls -ld *(/om[1,3])' # Show three newest directories. "om" orders by modification. "[1,3]" works like Python slice.
alias lsize='ls -l */**(Lk+100)' # List all files larger than 100kb in this tree
alias lvd='ls -ld **/*(/^F)' # recursively list any empty sub-directories
alias l='ls -lph' # size,show type,human readable
alias la='ls -lAph' # long list,show almost all,show type,human readable
alias lt='ls -lAtph' # long list,sorted by date,show type,human readable
此 grep 示例中的缩进是应有的,这不是错误。我的函数应该基本上做同样的事情,只是将两个星号之间的内容作为参数(在本例中为git rebase
和ls -la
)。
但它并没有做同样的事情,我不知道为什么:
$ graliases git branch
git branch
alias lnew='ls -ld *(/om[1,3])' # Show three newest directories. "om" orders by modification. "[1,3]" works like Python slice.
alias findAllIPs="nmap -sP 192.168.1.* | grep -oE '192.168.1.[0-9]*'"
alias findLocalIP="ifconfig | grep -oE 'inet 192.168.1.[0-9]*'"
alias apls="apt list"
alias gcR='git reset "HEAD^"'
alias gdi='git status --porcelain --short --ignored | sed -n "s/^!! //p"'
alias ggf="git ls-files | grep -i"
alias gCl='git status | sed -n "s/^.*both [a-z]*ed: *//p"'
alias gpc='git push --set-upstream origin "$(git-branch-current 2> /dev/null)"'
alias gpp='git pull origin "$(git-branch-current 2> /dev/null)"
&& git push origin "$(git-branch-current 2> /dev/null)"'
alias gwig="git update-index --assume-unchanged"
alias gwuig="git update-index --no-assume-unchanged"
% graliases ls -la
ls -la
alias lnew='ls -ld *(/om[1,3])' # Show three newest directories. "om" orders by modification. "[1,3]" works like Python slice.
alias findAllIPs="nmap -sP 192.168.1.* | grep -oE '192.168.1.[0-9]*'"
alias findLocalIP="ifconfig | grep -oE 'inet 192.168.1.[0-9]*'"
alias apls="apt list"
alias gcR='git reset "HEAD^"'
alias gdi='git status --porcelain --short --ignored | sed -n "s/^!! //p"'
alias ggf="git ls-files | grep -i"
alias gCl='git status | sed -n "s/^.*both [a-z]*ed: *//p"'
alias gpc='git push --set-upstream origin "$(git-branch-current 2> /dev/null)"'
alias gpp='git pull origin "$(git-branch-current 2> /dev/null)"
&& git push origin "$(git-branch-current 2> /dev/null)"'
alias gwig="git update-index --assume-unchanged"
alias gwuig="git update-index --no-assume-unchanged"
根据1,2,$*
是此用例的正确变量。甚至该行也echo "$*"
打印出了预期的结果。不幸的是,我还没有$*
在 zsh 手册页中找到明确的解释。
为什么我的功能不能正常工作?
答案1
图案grep
看起来不对。命令行的经验法则是,单引号内的所有内容均按字面意思处理,而当未加引号或双引号内时,shell 根据其规则(通配、分割、参数扩展等)扩展此类字符串。在你的情况下命令
grep -E '*"$*"*' ~/.dotfiles/zsh/aliases.zsh
表示按字面意思传递给grep
字符串*"$*"*
,以便 grep 将此模式解释为星号,后跟双引号,后跟重复零次或多次的美元符号 ( *
),后跟重复零次或多次的双引号 ( *
)。这不是你所期望的。
您想将$*
其视为变量(在本例中为双引号),因此请关闭它前面的单引号字符串,然后再打开:
grep -E '*'"$*"'*' ~/.dotfiles/zsh/aliases.zsh
但我根本不明白这些星星的原因(你不想 grep 星星,是吗?),在我看来,你可以将其简化为
grep -E "$*" ~/.dotfiles/zsh/aliases.zsh