1

我以为我的 bash-fu 足够强大,但显然不是。我似乎无法弄清楚这一点。我想做这样的事情:

  var="XXXX This is a line"
  word_to_replace="XXXX"
  # ...do something
  echo "Done:${var}"
  Done:     This is a line

基本上我想用空格快速替换单词中的所有字符,最好是一步完成。请注意,如果它使事情更容易var目前将在字符串的开头,尽管它可能有前导空格(需要保留)。

在 python 中,我可能会这样做:

>>> var="XXXX This is a line"
>>> word_to_replace="XXXX"
>>> var=var.replace(word_to_replace, ' '*len(word_to_replace))
>>> print("Done:%s" % var)
Done:     This is a line
4

4 回答 4

3

这是您可以使用 shell 参数扩展和 sed 命令的组合的一种方法。

$ var="XXXX This is a line"
$ word_to_replace="XXXX"
$ replacement=${word_to_replace//?/ }
$ sed "s/$word_to_replace/$replacement/" <<<"$var"
     This is a line

?匹配任何字符并${var//find/replace}进行全局替换,因此变量$replacement的长度与 相同$word_to_replace,但仅由空格组成。

您可以以通常的方式将结果保存到变量中:

new_var=$(sed "s/$word_to_replace/$replacement/" <<<"$var")
于 2017-05-04T09:02:56.910 回答
1

在普通的 Bash 中:

如果我们知道要替换的单词:

$ line=" foo and some"
$ word=foo
$ spaces=$(printf "%*s" ${#word} "")
$ echo "${line/$word/$spaces}"
     and some

如果我们不这样做,我们可以将字符串分开以找到前导词,但这有点难看:

xxx() {
   shopt -s extglob              # for *( )
   local line=$1
   local indent=${line%%[^ ]*}   # the leading spaces
   line=${line##*( )}            # remove the leading spaces
   local tail=${line#* }         # part after first space 
   local head=${line%% *}        # part before first space...
   echo "$indent${head//?/ } $tail"  # replace and put back together
}
$ xxx "  word on a line"
        on a line

如果该行只有一个单词,head并且tail都设置为该单词,这也会失败,我们需要检查是否有空格并分别处理这两种情况。

于 2017-05-04T10:24:27.307 回答
0

我使用 GNU awk:

echo "$title" | gawk '{gsub(/./, "*"); print}'

这将用星号替换每个字符。

编辑。综合答案:

$ export text="FOO hello"
$ export sub="FOO"
$ export space=${sub//?/ }
$ echo "${text//$sub/$space}"
    hello
于 2017-05-04T08:54:12.440 回答
0

使用sed

#!/usr/bin/env sh

word_to_replace="XXXX"
var="$word_to_replace This is a line"

echo "Done: $var"

word_to_replace=$(echo "$word_to_replace" | sed 's,., ,g')
var="$word_to_replace This is a line"
echo "Done: $var"
于 2017-05-04T08:58:24.453 回答