2017-05-04 101 views
1

我认为我的bash-fu足够强大,但显然它不是。我似乎无法弄清楚这一点。我愿做这样的事情:Bash:用等于单词长度的空格替换单词

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 
+0

是否必须使用空格填充最后一个字符串? – RomanPerekhrest

+0

@RomanPerekhrest是的。我希望用空格替换单词的长度,就像标题提到的一样。 – lonetwin

回答

2

这里有一种方法,你可以做到这一点,使用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") 
+1

您不需要'sed',如果'$ word_to_replace'包含斜线或某些特殊字符(如点,星号等)可能会令人惊讶 – Igor

0

我使用了GNU AWK:

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

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

编辑。统一的答案:

$ export text="FOO hello" 
$ export sub="FOO" 
$ export space=${sub//?/ } 
$ echo "${text//$sub/$space}" 
    hello 
+2

这将用星号替换每个字符,这不是已经问过的问题,用'tr -c'''*'可以更容易实现' – ceving

+0

然后将'tr'或其他任何内容应用到'$ word_to_replace'并使用bash字符串替换。 – Igor

+0

顺便说一下,'tr -c'''*''将会替换新行,如果有的话。 – Igor

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" 
+0

这看起来像一个答案,但不是我正在寻找的,因为它重新创建线条而不是替换单词。例如,如果该行在替换之前有空格,就像我在问题中提到的那样,该解决方案将如何适应?好的方法是',我可能必须这样做 - 分割线,用空格替换单词中的所有字符并重新创建线。 – lonetwin

+0

'newline = $ {oldline // $ word_to_replace/$ replacement'' – Igor

+0

@Igor ehe ...'$ replacement'是什么? – lonetwin

1

在平原击:

如果我们认识这个字的替换:

$ 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 

如果行上只有一个单词,headtail都设置为该单词,那么也会失败,因此我们需要检查是否有空格并分别处理这两个单例。