2017-07-26 38 views
0

我的隊友之前在unix SE上問過這個問題,但他問的是錯誤的。他也沒有得到正確的答案。在bash中每個字母定義變量的回聲不同

無論如何,我試圖讓我的bash腳本處理變量中的每個字符,並且每個字母都回顯特定的字符串,直到達到最後。這是我到目前爲止有:

#!/bin/bash 

echo Word? 
read -r -p '' foo 
# $foo is set to 'Mammals and Bricks' by user. 

wordlength=${#foo} 
$wordlength says 18, so start on character 1. 
'M' is first letter received in $foo, so echo '{m,M}' 
'a' is second letter received in $foo, so echo '{a,A}' 
'm' is third letter received in $foo, so echo '{m,M}' 
'm' is fourth letter received in $foo, so echo '{m,M}' 
'a' is the fifth letter received in $foo, so echo '{a,A}' 
'l' is the sixth letter received in $foo, so echo '{l,L}' 
's' is the seventh letter received in foo, so echo '{s,S}' 
' ' is the eighth, so echo '\ ' 
........ 
'c' is sixteenth letter received in $foo, so echo '{c,C}' 
'k' is seventeenth letter received in $foo, so echo '{k,K}' 
's' is eighteenth letter received in $foo, so echo '{s,S}' 

這裏是它會是什麼樣子對用戶端:

Word? 

哺乳動物和磚

{m,M}{a,A}{m,M}{m,M}{a,A}{l,L}{s,S} {a,A}{n,N}{d,D} {b,B}{r,R}{i,I}{c,C}{k,K}{s,S} 

哪個會是什麼輸出恰好爲。你會看到所有上面的原始字符。

任何人都知道如何做到這一點?

回答

1

開始通過在字符串中的字符循環:

foo=string 
for ((i=0; i<${#foo}; i++)); do 
    echo "${foo:$i:1}" 
done 

(參考:How to perform a for loop on each character in a string in BASH?

現在用case語句替換回聲聲明:

foo=string 
for ((i=0; i<${#foo}; i++)); do 
    case "${foo:$i:1}" in 
    a) 
     echo "Do something with a here"; 
     ;; 
    [bB]) 
     echo "Do something with b or B here"; 
     ;; 
    esac 
done 
2

下面是一個解決方案與GNU sed,如果你不介意使用它:

sed 's/[a-zA-Z]/{\l&,\u&}/g' <<< "$foo" 

\l\u是GNU擴展到sed,分別將下一個字符轉爲小寫和大寫。

[編輯]這裏是bash一個解決方案,因爲你沒有GNU sed

while read -r -n1; do 
    if [[ "${REPLY^}" == [A-Z] ]]; then 
     printf '{%c,%c}' "${REPLY,}" "${REPLY^}" 
    else 
     printf '%c' "$REPLY" 
    fi 
done <<< "$foo" 
echo 

[編輯]附:不幸的是,這在OS X Yosemite上不起作用,因爲$ {var,}和$ {var ^}結構是在bash v4中添加的,但是MacOS僅隨bash v3.2.57一起發佈(這是因爲bash v4在GPL v3,Apple不想遵守)。感謝@GordonDavisson爲此添加。

因此,這裏是應該與你的bash v3上運行的解決方案:

printf '%s\n' "$foo" \ 
| while read -d '' -r -n1; do 
    lowercase="$(printf '%c' "$REPLY" | tr '[:upper:]' '[:lower:]')" 
    uppercase="$(printf '%c' "$REPLY" | tr '[:lower:]' '[:upper:]')" 
    if [ "$lowercase" != "$uppercase" ]; then 
     printf '{%c,%c}' "$lowercase" "$uppercase" 
    else 
     printf '%c' "$REPLY" 
    fi 
done 
+0

嗯......當我跑我的輸出是這樣的:'{LM,UM} {LA,UA} {LM ,um} {lm,um} {la,ua} {ll,ul} {ls,us} {la,ua} {ln,un} {ld,ud} {lB,uB} {lr,ur} {li ,UI} {LC,UC} {LK,英國} {LS,我們}'。我使用OS X Yosemite btw – leetbacoon

+0

然後你可能使用的是經典的sed,而不是GNU sed(注意GNU sed可能在OSX上可用)。我在純bash中添加了一個解決方案。 – xhienne

+1

@xhienne不幸的是,'$ {var,}'和'$ {var ^}'構造是在bash v4中添加的,但是macOS只隨bash v3.2.57一起發佈。 (這是因爲bash v4是根據GPL v3獲得許可的,蘋果不想遵守。) –