1
votes

tri des listes avec des minuscules, des majuscules et des nombres

Je voudrais nettoyer et trier la sortie renvoyée d'une commande bash.

Actuellement, la sortie est assez désorganisée:

com.adobe.lightroom
com.apple.airplay
com.apple.bonjour
com.apple.safari
00000000-0000-0000-A000-4A414D460003
0343C308-CE79-4D3B-90F5-D32122234378
C145DC85-D209-4062-BC35-E24D27BC399E
E38D2355-BD4D-45FE-9F1E-979F2493099A
EEE4C3FC-6104-4B32-A9C7-D708E30EB86C


Je souhaite placer les éléments en minuscules en haut de la liste, les trier par ordre alphabétique, puis placer les chaînes UUID les plus longues en bas de la liste.

00000000-0000-0000-A000-4A414D460003
C145DC85-D209-4062-BC35-E24D27BC399E
com.adobe.lightroom
E38D2355-BD4D-45FE-9F1E-979F2493099A
com.apple.safari
EEE4C3FC-6104-4B32-A9C7-D708E30EB86C
com.apple.airplay
com.apple.bonjour
0343C308-CE79-4D3B-90F5-D32122234378


3 commentaires

Bienvenue dans stackoverflow. On s'attend à ce que vous ayez tenté de résoudre le problème avant de publier une question - veuillez modifier votre message pour ajouter des références, des tentatives existantes ou du code pertinent.


avez-vous essayé d'utiliser cat | trier ou trier ?


salut @azbarcea, j'ai essayé un tri au départ et je me suis retrouvé avec 00000 en haut et le com. * en bas.


3 Réponses :


1
votes

Essayez ceci:

sort myfile.txt | tee >(grep -Pv "^[0-9A-F]{8}.+") >(grep -P "^[0-9A-F]{8}.+") > /dev/null

Il trie d'abord les fichiers, puis greps pour les lignes UUID, et les affiche en dernier.

Ma définition d'un UUID est n'importe quelle ligne commençant par 8 caractères de: 0-9 ou AF (majuscule).


1 commentaires

@oguzismail en utilisant | indiqué comme dans votre exemple produirait une sortie différente (pas de sortie - pour être plus exact). Utilisation de trier mon.txt | tee> (grep -Pv "^ [0-9A-F] {8} -. +") | (grep -P "^ [0-9A-F] {8}. +") filtrer uniquement les lignes UUID, en supprimant toutes les autres (par exemple com. * )



1
votes

Veuillez essayer ce qui suit:

perl -e '
print map { $_->[0] }
    sort { $a->[1] <=> $b->[1] or $a->[0] cmp $b->[0] }
    map { [$_, /^[a-z]/ ? 0 : 1] } <>;
' list.txt

Résultat:

com.adobe.lightroom
com.apple.airplay
com.apple.bonjour
com.apple.safari
00000000-0000-0000-A000-4A414D460003
0343C308-CE79-4D3B-90F5-D32122234378
C145DC85-D209-4062-BC35-E24D27BC399E
E38D2355-BD4D-45FE-9F1E-979F2493099A
EEE4C3FC-6104-4B32-A9C7-D708E30EB86C

Son approche primitive consiste simplement à ajouter une marque "A" ou " B "dans la deuxième colonne pour distinguer les éléments en minuscules des autres.

Comme alternative, si perl est votre option, veuillez essayer:

while IFS= read -r line; do
    if [[ $line == [a-z]* ]]; then
        printf "%s%c%s\n" "$line" $'\t' "A"
    else
        printf "%s%c%s\n" "$line" $'\t' "B"
    fi
done < list.txt | sort -t $'\t' -k2 -k1 | cut -f1


2 commentaires

Wow, super idée. Vous pouvez ajouter une lettre en utilisant une simple expression régulière avec sed : cat list.txt | sed 's / ^ [a-z] / A & /; t; s / ^ / B /;' | trier | cut -c2- , cela devrait être en fait très rapide.


Bien mieux que le mien :)



0
votes

Un "sort -r" inversé fera cela. Cela fonctionne parce que si vous regardez la table ascii , vous remarquerez que les caractères alpha minuscules sont à la fin.

$ cat output | perl -e 'print sort {substr($b,0,1) cmp substr($a,0,1) || $a cmp $b} <>;'
com.adobe.lightroom
com.apple.airplay
com.apple.bonjour
com.apple.safari
E38D2355-BD4D-45FE-9F1E-979F2493099A
EEE4C3FC-6104-4B32-A9C7-D708E30EB86C
C145DC85-D209-4062-BC35-E24D27BC399E
00000000-0000-0000-A000-4A414D460003
0343C308-CE79-4D3B-90F5-D32122234378

Cependant, cela ne trie pas les minuscules dans l'ordre alpha. Passer à la puissance lexicale de perl.

$ cat output
00000000-0000-0000-A000-4A414D460003
C145DC85-D209-4062-BC35-E24D27BC399E
com.adobe.lightroom
E38D2355-BD4D-45FE-9F1E-979F2493099A
com.apple.safari
EEE4C3FC-6104-4B32-A9C7-D708E30EB86C
com.apple.airplay
com.apple.bonjour
0343C308-CE79-4D3B-90F5-D32122234378

$ sort -r output
com.apple.safari
com.apple.bonjour
com.apple.airplay
com.adobe.lightroom
EEE4C3FC-6104-4B32-A9C7-D708E30EB86C
E38D2355-BD4D-45FE-9F1E-979F2493099A
C145DC85-D209-4062-BC35-E24D27BC399E
0343C308-CE79-4D3B-90F5-D32122234378
00000000-0000-0000-A000-4A414D460003

Décomposition de la commande perl

  • "-e" exécute le script Perl suivant
  • affiche les résultats du tri où tout ce qui se trouve à l'intérieur de {} est la comparaison de tri personnalisée
  • "substr ($ b, 0,1) cmp substr ($ a, 0,1)" Premier tri inversé sur le premier caractère uniquement. C'est un tri inversé car $ b est le premier
  • "||" ou s'ils ont la même valeur
  • "$ a comp $ b" Effectue un tri normal sur la ligne pour les valeurs qui ont le même premier caractère.
  • lit depuis stdin


2 commentaires

Salut @waltde, merci. C'est assez proche mais le tri -r le fait par ordre alphabétique à l'envers.


@JimSmith ma miss. J'ai mis à jour la réponse pour en tenir compte.