2017-05-04 104 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都設置爲該單詞,那麼也會失敗,因此我們需要檢查是否有空格並分別處理這兩個單例。