2017-07-26 2 views
0

Mon copain a demandé cela avant sur l'unix SE, mais il a demandé tort. Il n'a pas obtenu de réponse utile non plus.Echo texte différent par lettre d'une variable définie dans bash

Quoi qu'il en soit, j'essaie de faire en sorte que mon script bash traite chaque caractère dans une variable et fasse écho à une certaine chaîne par lettre jusqu'à ce qu'elle atteigne la dernière. Voici ce que j'ai jusqu'à présent:

#!/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}' 

Et voici ce qu'il ressemblerait à la fin de l'utilisateur:

Word? 

Mammifères et Briques

{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} 

Quel est ce qu'il sortie exactement. Vous verriez tout ce qui précède en caractères bruts.

Quelqu'un sait-il comment faire?

Répondre

1

Commencez par une boucle à travers les personnages de votre chaîne:

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

(Référence: How to perform a for loop on each character in a string in BASH?)

remplacer maintenant la déclaration d'écho avec une déclaration de cas:

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

Voici une solution avec GNU sed, si cela ne vous dérange pas de l'utiliser:

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

\l et \u sont des extensions GNU à sed qui transforment respectivement le caractère suivant en minuscules et majuscules.

[modifier] Et voici une solution avec bash puisque vous ne l'avez pas 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 

[modifier] post-scriptum Malheureusement, cela ne fonctionnera pas sous OS X Yosemite car les constructions $ {var,} et $ {var ^} ont été ajoutées dans bash v4, mais MacOS ne contient que bash v3.2.57 (car bash v4 est sous licence GPL v3, que Apple ne veut pas respecter). Merci à @GordonDavisson pour l'avoir ajouté.

Voici donc une solution qui devrait fonctionner avec votre 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

Hmm ... Quand je lance que ma sortie ressemble à ceci: '{Lm iM} {la, ua} {lm , um} {lm, um} {la, ua} {ll, ul} {ls, nous} {la, ua} {ln, un} {ld, ud} {lB, uB} {lr, ur} {li , ui} {lc, uc} {lk, uk} {ls, nous} '. J'utilise OS X Yosemite btw – leetbacoon

+0

Alors vous utilisez probablement un sed classique, pas GNU sed (notez que GNU sed est probablement disponible sur OSX). J'ai ajouté une solution en bash pur. – xhienne

+1

@xhienne Malheureusement, les constructions '$ {var,}' et '$ {var ^}' ont été ajoutées dans bash v4, mais macOS n'est fourni qu'avec bash v3.2.57. (C'est parce que bash v4 est sous licence GPL v3, ce que Apple ne veut pas se conformer.) –