J'ai une chaîne d'entrée comme:
arg1.arg2.arg3.arg4.arg5
La sortie que je veux est:
arg5.arg4.arg3.arg2.arg1
Ce n'est pas toujours 5 arguments, pourrait être de 2 à 10.
Comment puis-je faire cela dans un script bash?
J'ai une chaîne d'entrée comme:
arg1.arg2.arg3.arg4.arg5
La sortie que je veux est:
arg5.arg4.arg3.arg2.arg1
Ce n'est pas toujours 5 arguments, pourrait être de 2 à 10.
Comment puis-je faire cela dans un script bash?
Utilisation d'une combinaison de tr
+ tac
+paste
$ tr '.' $'\n' <<< 'arg1.arg2.arg3.arg4.arg5' | tac | paste -s -d '.'
arg5.arg4.arg3.arg2.arg1
Si vous préférez toujours bash, vous pouvez le faire de cette façon,
IFS=. read -ra line <<< "arg1.arg2.arg3.arg4."
let x=${#line[@]}-1;
while [ "$x" -ge 0 ]; do
echo -n "${line[$x]}.";
let x--;
done
Utilisation perl
,
$ echo 'arg1.arg2.arg3.arg4.arg5' | perl -lne 'print join ".", reverse split/\./;'
arg5.arg4.arg3.arg2.arg1
Si cela ne vous dérange pas un petit peu de
python
:Exemple:
s.split(".")
génère une liste contenant.
des sous-chaînes séparées,[::-1]
inverse la liste et".".join()
joint les composants de la liste inversée avec.
.la source
Vous pouvez le faire avec une seule
sed
invocation:cela utilise le tampon de maintien pour obtenir une nouvelle ligne de début dans l'espace de motif et l'utilise pour faire des permutations jusqu'à ce que la nouvelle ligne ne soit plus suivie par aucun point auquel point il supprime le point de tête de l'espace de motif et remplace la nouvelle ligne par un point.
Avec BRE et un regex légèrement différent:
Si l'entrée se compose de plusieurs lignes et que vous souhaitez inverser l'ordre sur chaque ligne:
la source
Solution SED:
la source
Avec
zsh
:Pour conserver les éléments vides:
s:.:
: divisé sur.
Oa
: Tableau de tri en sens inverse un rray indice o rderj:.:
: rejoignez-nous.
.@
:"$@"
extension à la manière des guillemets doubles pour que l'expansion ne soit pas supprimée à vide.L'
bash
équivalent POSIX (ou ) pourrait ressembler à:(notez que
zsh
(ensh
émulation),yash
et certainspdksh
shells basés sur ne sont pas POSIX à cet égard en ce qu'ils traitent$IFS
comme un séparateur de champ au lieu d'un délimiteur de champ)Là où il diffère de certaines des autres solutions données ici, c'est qu'il ne traite pas
zsh
spécialement le caractère de nouvelle ligne (et dans le cas de , le NUL), qui$'ab.cd\nef.gh'
serait inversé en$'gh.cd\nef.ab'
, pas$'cd.ab\ngh.ef'
ou$'gh.ef.cd.ab'
.la source
IFS="."; set -f; set -- $string$IFS; for i; do rev="$i$IFS$rev"; done; printf '%s\n' "${rev%$IFS}"
?for i; do
qui n'est pas (encore) POSIX même s'il est supporté par tous les shells POSIX que je connais). C'est juste que cette solution est une traduction directe dezsh
celle (divisée en tableau, tableau inversé, joindre des éléments de tableau) mais en utilisant des opérateurs POSIX uniquement. (J'ai changé lestring=$string$IFS; set -- $string
enset -- $string$IFS
car cela semble fonctionner de manière cohérente entre les shells, merci).Je vois que Rahul a déjà posté une solution bash native (entre autres), qui est une version plus courte de la première que j'ai inventée:
mais je n'ai pas pu m'arrêter là, et j'ai ressenti le besoin d'écrire une solution récursive centrée sur bash:
la source
Je n'ai pas vu de
awk
réponse, alors en voici une:la source
Pure Bash, nécessite une période de fin en entrée:
À utiliser
printf %s "$g"
si l'un des éléments en pointillé peut commencer par un trait d'union.la source