2010-04-05 23 views
6

J'ai un devoir où je dois prendre l'entrée d'un fichier et enlever continuellement le premier mot d'une ligne et l'ajouter à la fin de la ligne jusqu'à ce que toutes les combinaisons aient été faites. Je ne sais vraiment pas par où commencer et je serais reconnaissant pour toute sorte de direction.Comment faire un décalage circulaire de chaînes dans bash?

La partie qui m'a confondu est que cela est supposé être effectué sans l'utilisation de tableaux. Je ne cherche pas seulement quelqu'un pour résoudre le problème pour moi, je cherche juste une direction.

ENTRÉE SAMPLE:

Pipes and Filters 
Java Swing 
Software Requirements Analysis 

SORTIE EXEMPLE:

Analysis Software Requirements 
Filters Pipes and 
Java Swing 
Pipes and Filters 
Requirements Analysis Software 
Software Requirements Analysis 
Swing Java 
+0

similaires: [Comment est-ce que je divise une chaîne sur un délimiteur dans Bash?] (http://stackoverflow.com/q/918886/55075) à SO – kenorb

Répondre

6

Quelques petits morceaux qui devraient aider: lorsque vous appelez une fonction avec une chaîne, la chaîne est divisée en plusieurs arguments (le positional parameters, nommé $n, où n sont des nombres entiers commençant à 1) sur les caractères de la variable $IFS (qui par défaut des espaces, des onglets et des sauts de ligne)

function first() { 
    echo $1 
} 
first one two three 
# outputs: "one" 

$* and [email protected] vous donner tous les paramètres de position, dans l'ordre. Deuxièmement, la variable spéciale $# contient le nombre d'arguments d'une fonction.

Troisièmement, shift rejette le premier paramètre positionnel et déplace tous les autres de un.

function tail() { 
    shift 
    echo $* 
} 

Quatrièmement, vous pouvez capturer la sortie des commandes et des fonctions en utilisant `...` or $(...)

rest=`tail $*` 

Cinquième, vous pouvez envoyer la sortie d'une commande à l'entrée d'un autre à l'aide du pipe character (|):

seq 5 | sort 
+0

C'était très utile. J'ai maintenant compris la plupart des tâches et je dois simplement trouver comment stocker toutes ces chaînes afin de les trier par ordre alphabétique. –

+0

@Kyle: voir les nouveaux conseils. – outis

+0

Merci beaucoup outis, j'apprécie vraiment l'aide. J'aime la simplicité de ta fonction tail(). –

3

Pour vous aider à démarrer, consultez le read builtin:

while read first_word rest_of_the_line; do 
    ... your code here ... 
done 

Vous avez également besoin d'un moyen d'alimenter votre fichier d'entrée dans cette boucle.

+0

Merci beaucoup, j'apprécie l'aide. –

0

L'extension de paramètre vous permet de découper des parties d'une variable.

0

Ceci est une courte démonstration. Parcourez les mots, prenez le dernier mot et placez-vous devant la chaîne. jusqu'à ce que la chaîne finale soit la même que l'original.

#!/bin/bash  
    s="Software Requirements Analysis" 
    org="$s" 
    while true 
    do 
     last=${s##* } #Analysis 
     front=${s% *} #Software Requirements 
     s="$last $front" 
     echo $s 
     case "$s" in 
     "$org") break;; 
     esac 
    done 

vous devriez pouvoir faire le reste en utilisant un fichier.

+0

Si je voulais supprimer le premier mot et l'ajouter à la fin, quels changements apporterais-je aux deux lignes suivantes? derniers = $ {s} ## * #analysis avant = $ {s}% * #software Exigences Je ne comprends pas ce que le s ## * et s% * signifie. Merci beaucoup pour votre réponse, c'est aussi très utile. –

+0

Il n'est pas espacer correctement mes lignes dans le commentaire, désolé pour le fait d'être si désordonné. –

+0

voir ici: http://en.tldp.org/LDP/abs/html/string-manipulation.html sous 'substring removal' pour des exemples. vous devriez être en mesure d'avoir une idée de la façon dont cela fonctionne et de faire le nécessaire vous-même. – ghostdog74

2

Permettez-moi de vous montrer un exemple de travail rapide basé sur @outis answer:

strings="string1 string2 string3" 
next() { echo $1; } 
rest() { shift; echo $*; } 
for i in $strings; do 
    echo $(next $strings) 
    strings=$(rest $strings) 
done 

Ou autrement-tour si vous êtes intéressé à traverser par séquence:

strings="string1 string2 string3" 
next() { echo $1; } 
rest() { shift; echo $*; } 
totalWords=$(c() { echo $#; }; c $strings) 
for i in `seq -w 1 $totalWords`; do 
    echo $i: $(next $strings) 
    strings=$(rest $strings) 
done 
+0

Comme la simplicité des fonctions next() et rest(); +1 – razzed