Bash:用等于单词长度的空格替换单词
Bash: Replace word with spaces equal to the length of the word
我以为我的 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
我使用 GNU Awk:
echo "$title" | gawk '{gsub(/./, "*"); print}'
这会将每个字符替换为星号。
编辑。综合答案:
$ export text="FOO hello"
$ export sub="FOO"
$ export space=${sub//?/ }
$ echo "${text//$sub/$space}"
hello
使用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"
这是您可以使用的一种方法,结合使用 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")
简而言之Bash:
如果我们知道要替换的单词:
$ line=" foo and some"
$ word=foo
$ spaces=$(printf "%*s" ${#word} "")
$ echo "${line/$word/$spaces}"
and some
如果我们不这样做,我们可以将字符串分开以找到前导词,但这有点难看:
xxx() {
shopt -s extglob # for *( )
local line=
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
都设置为那个词,我们需要检查是否有 space 并分别处理这两种情况。
我以为我的 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
我使用 GNU Awk:
echo "$title" | gawk '{gsub(/./, "*"); print}'
这会将每个字符替换为星号。
编辑。综合答案:
$ export text="FOO hello"
$ export sub="FOO"
$ export space=${sub//?/ }
$ echo "${text//$sub/$space}"
hello
使用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"
这是您可以使用的一种方法,结合使用 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")
简而言之Bash:
如果我们知道要替换的单词:
$ line=" foo and some"
$ word=foo
$ spaces=$(printf "%*s" ${#word} "")
$ echo "${line/$word/$spaces}"
and some
如果我们不这样做,我们可以将字符串分开以找到前导词,但这有点难看:
xxx() {
shopt -s extglob # for *( )
local line=
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
都设置为那个词,我们需要检查是否有 space 并分别处理这两种情况。