Comment colorer les colonnes de sortie de ls?

8

Le titre en dit long: j'aimerais obtenir ces colonnes aux couleurs vives de la sortie de quelque chose comme ls -al, disons, comme dans la réponse de 10basetom à cette question .

Capture d'écran d'extrait de code mis en évidence par la syntaxe à partir d'une réponse liée

Pirx
la source
Eh bien, c'est une bonne idée! Mais sur quel OS êtes-vous?
JakeGould
2
Cela semble être (incorrectement) la syntaxe Bash mise en évidence par le logiciel SE. Il semble que ce ne soit pas coloré par colonne, mais plutôt que les chiffres (nombres) obtiennent une couleur et que tout commençant par un majuscule en obtienne une autre. La coloration par colonne est réalisable mais assez différente.
Bob
3
Dans le sens général, vous pouvez diviser la sortie sur les séparateurs de colonnes avec sedou awket insérer une séquence d'échappement ANSI .
Bob
EN RELATION
Tyson
Je suis sur le sous-système Windows 10 Ubuntu, mais en transition vers macOS (étant donné le désastre complet que WinX s'est avéré être ...)
Pirx

Réponses:

8

C'est faisable avec awk. Malheureusement, comme le format de ls -ln'est pas spécifié, il n'est pas possible de trouver une solution qui fonctionnera sur tous les systèmes, donc un ajustement de la couleur à utiliser pour quelle colonne sera nécessaire sur certains systèmes.


Tout d'abord, nous voulons conserver les espaces d'origine utilisés par ls -l. Sinon, l'alignement des colonnes sera incorrect. Nous pouvons le faire avec l' FPAToption, grâce à cette réponse SO :

ls -la | awk '
    BEGIN {
        FPAT = "([[:space:]]*[^[:space:]]+)";
        OFS = "";
    }

Dans awkchaque param position ( $1, $2, etc.) se réfère à un champ, soit une colonne sur la ligne courante. L' FPAToption ci-dessus a redéfini chaque champ pour inclure tous les espaces précédents, donc lorsque vous printle reculez, il conserve les espaces afin que les colonnes restent dans la même position.

Maintenant, nous pouvons simplement modifier chaque champ pour insérer le code couleur , puis imprimer la sortie modifiée:

    {
        $2 = "\033[31m" $2 "\033[0m";
        $3 = "\033[36m" $3 "\033[0m";
        $4 = "\033[36m" $4 "\033[0m";
        $5 = "\033[31m" $5 "\033[0m";
        $6 = "\033[36m" $6 "\033[0m";
        $7 = "\033[36m" $7 "\033[0m";
        $8 = "\033[31m" $8 "\033[0m";
        print
    }
'

Notez que chaque colonne est réinitialisée par défaut ( 0entre [et m) par la suite. Si vous souhaitez que la couleur s'exécute sur plusieurs colonnes, vous pouvez omettre ce code. Personnellement, je préfère spécifier chaque colonne indépendamment.


Vous pouvez définir une commande réutilisable dans votre .bashrc. Par exemple:

lsc() {
    ls -la | awk '
        BEGIN {
            FPAT = "([[:space:]]*[^[:space:]]+)";
            OFS = "";
        }
        {
            $2 = "\033[31m" $2 "\033[0m";
            $3 = "\033[36m" $3 "\033[0m";
            $4 = "\033[36m" $4 "\033[0m";
            $5 = "\033[31m" $5 "\033[0m";
            $6 = "\033[36m" $6 "\033[0m";
            $7 = "\033[36m" $7 "\033[0m";
            $8 = "\033[31m" $8 "\033[0m";
            print
        }
    '
}

Vous devrez peut-être redémarrer votre bashsession (ou l'exécuter source ~/.bashrc) pour que cette définition de fonction s'exécute.

De là, vous pouvez simplement appeler lsc, ce qui devrait vous donner la sortie que vous désirez:

Capture d'écran de la sortie en couleur

Bob
la source
Les gars géniaux, c'est presque ce que je veux ;-) Sérieusement, cependant, j'aimerais ajouter une touche supplémentaire et faire colorer les noms de fichiers. ls -al --color = auto ferait cela, mais si j'ajoute simplement l'option --color aux solutions ci-dessus, les codes de couleur semblent être supprimés. Pouvons-nous obtenir awk pour les garder?
Pirx
Deuxième commentaire, c'est plus par curiosité: dans la réponse à laquelle j'ai fait référence dans ma question d'origine, il semble que 10basetom n'ait utilisé aucune des options ci-dessus et avait toujours les colonnes colorées. Je me demande si c'est parce qu'il a utilisé une version différente de ls, ou un terminal intelligent sophistiqué?
Pirx
@Pirx La coloration dans la réponse est appliquée par le logiciel Stack Exchange. Ça ne vient pas de leur terminal. C'est simplement parce que la sortie a été collée dans un bloc de code et que la question avait une balise bash , qui essaie automatiquement d'appliquer la coloration syntaxique Bash à toutes les balises de code dans la question et les réponses ... ce qui est en fait incorrect dans ce cas. Même raison pour laquelle les chaînes du code sont rouges dans ma réponse, même si je ne les ai pas intentionnellement colorées.
Bob
1
@Pirx Use --color=always. Tant que vous n'appliquez pas de couleurs différentes à la colonne du nom de fichier ( $9dans mon exemple), vous devez awkles passer.
Bob
@Pirx Side note, --color=alwaysest une extension GNU donc si vous êtes sur un système non GNU (par exemple macOS, autres BSD), vous devrez soit installer la version GNU, soit utiliser une alternative .
Bob
6

Cela imprimera la deuxième colonne ls -alFen rouge, la troisième à la huitième en bleu et la neuvième en noir:

ls -alF | awk -v black=$(tput setaf 0) -v red=$(tput setaf 1) -v blue=$(tput setaf 4) '{$2=red $2; $3= blue $3; $9=black $9} 1'

Il s'agit simplement d'un exemple. Vous pouvez personnaliser cela selon le contenu de votre cœur.

Pour ceux qui préfèrent leur code étalé sur plusieurs lignes:

ls -alF | awk -v black=$(tput setaf 0) \
    -v red=$(tput setaf 1) \
    -v blue=$(tput setaf 4) \
    '{
        $2=red $2
        $3= blue $3
        $9=black $9
     }

     1'

Détails

tputest un utilitaire pour générer une grande variété de codes de contrôle pour votre terminal. Par exemple, tput setaf ndéfinit la couleur de premier plan nnpeut varier de 0 à 7

0  Black
1  Red
2  Green
3  Yellow
4  Blue
5  Magenta
6  Cyan
7  White

Vous pouvez en savoir plus sur tputses capacités de couleur ici .

Les variables code awk de Définit black, redet bluequi contiennent les codes de terminaux pour le noir, le rouge et le bleu, respectivement. Ces codes sont placés au début de la colonne que nous voulons colorer.

Une astuce est que les codes de couleur ne se réinitialisent pas d'eux-mêmes. Ainsi, quelle que soit la dernière couleur que vous spécifiez sur une ligne, à moins qu'une autre commande de couleur ne soit spécifiée, sera la couleur par défaut pour la ligne suivante.

John1024
la source
1
Huh, bon appel à définir des variables. Je ne savais pas que tu pouvais faire ça de l'intérieur awk! Je suggère que vous incluiez également le motif pour préserver l'alignement des colonnes :)
Bob
@Bob Et, j'aime votre FPATastuce pour garder l'espacement correct.
John1024