如何让 sed 知道 git grep 的 -w 标志?

问题描述 投票:0回答:1

我认为使用以下代码,执行类似

git_grep_sed -w pattern replacement
的操作将匹配整个单词。但是,如果匹配的是
if
,它也会匹配
fifa
中的子字符串。看起来
sed
部分实际上并没有在监听
-w
标志。

git_grep_sed() {
  local grep_options=()
  local search_pattern
  local replacement

  while [[ $1 =~ ^- ]]; do
    grep_options+=("$1")
    shift
  done

  search_pattern=$1
  replacement=$2

  git grep -l "${grep_options[@]}" "$search_pattern" | xargs sed -i "s/$search_pattern/$replacement/g"
}

这是为什么,如何解决?也许我必须使用其他东西来代替 sed?

bash git sed
1个回答
1
投票

因为你没有给

sed
任何标志。事实上,没有任何帮助。假设您有一个类似的文件

if consistency == "stiff":
    add_water()

git grep -w
将识别第一行,因为它本身包含单词
if
,但
sed
会很高兴地更改所有
if
实例,因为它不受约束。

您需要将单词边界锚添加到

sed
模式。不幸的是,这并不像看起来那么容易,因为不同版本的
sed
的做法不同。

unset use_osx_sed
if sed -e 's/[[:<:]]//' <<<"" >/dev/null 2>&1
then
  use_osx_sed=1
fi


git_grep_sed() {
  local grep_options=()
  local search_pattern
  local sed_search_pattern
  local replacement
  local full_word

  while [[ $1 =~ ^- ]]; do
    grep_options+=("$1")
    if [[ "$1" == -w ]]
    then
      full_word=1
    fi
    shift
  done

  search_pattern="$1"
  sed_search_pattern="$1"
  replacement="$2"

  if [[ -n "$full_word" ]]
  then
    if [[ -n "$use_osx_sed" ]]
    then
      sed_search_pattern="[[:<:]]$search_pattern[[:>:]]"
    else
      sed_search_pattern="\\<$search_pattern\\>"
    fi
  fi

  git grep -l "${grep_options[@]}" "$search_pattern" | xargs sed -i "s/$sed_search_pattern/$replacement/g"
}

(这个名字可能不准确。也许

non_gnu_sed
?我不知道这能达到什么程度,我只能在OSX和Linux上测试...)

© www.soinside.com 2019 - 2024. All rights reserved.