71 votes

Comment afficher $PATH comme un répertoire par ligne ?

Je n'arrive pas à trouver comment lister les différents chemins d'accès dans $PATH séparément pour qu'ils ressemblent à ceci :

/bin
/usr/bin
/usr/local/bin

Comment cela peut-il être fait ?

2voto

waltinator Points 32821

J'utilise les "Bash Path Functions" de Stephen Collyer (cf. son article dans le Linux Journal ). Il me permet d'utiliser la "liste séparée par deux points" comme type de données dans la programmation Shell. Par exemple, je peux produire une liste de tous les répertoires du répertoire courant par :

dirs="";for i in * ; do if [ -d $i ] ; then addpath -p dirs $i; fi; done  

Ensuite, listpath -p dirs produit une liste.

2voto

Joter Points 41

Explication de la réponse de @Cyrus

echo "${PATH//:/$'\n'}"

Notes :

Cotation ANSI-C - il explique $'some \ntext '

ShellExpansion de paramètre - il explique ${paramètre/pattern/string}, Si le pattern commence par '/', toutes les correspondances du pattern sont remplacées par la string.

Donc nous avons :

  1. un modèle / : qui commencent par '/' pour remplacer toutes les correspondances
  2. une chaîne $' \n ' qui est cité avec la contraction de $ 'anytext' pour traiter le symbole de nouvelle ligne ( \n ).

1voto

Eliah Kagan Points 111731

Un autre moyen pour AWK est de traiter chaque répertoire comme un élément distinct record plutôt que d'en faire une champ .

awk 'BEGIN{RS=":"} {print $0}' <<<"$PATH"

Je trouve cette syntaxe particulièrement intuitive. Mais, si vous le souhaitez, vous pouvez la raccourcir en faisant de l'élément print $0 implicite (c'est l'action par défaut, et 1 évalue à true, ce qui fait qu'il est fait pour chaque ligne) :

awk 'BEGIN{RS=":"} 1' <<<"$PATH"

Le séparateur d'enregistrements d'entrée et de sortie par défaut de AWK est la nouvelle ligne (saut de ligne). En définissant le séparateur d'enregistrement d'entrée ( RS ) à : avant de lire l'entrée, AWK analyse automatiquement un texte séparé par des deux points. $PATH en ses noms de répertoire constitutifs. AWK développe $0 à chaque enregistrement entier, le saut de ligne reste la sortie séparateur d'enregistrement, et aucune boucle ou gsub est nécessaire.

ek@Io:~$ echo "$PATH"
/home/ek/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
ek@Io:~$ awk 'BEGIN{RS=":"} {print $0}' <<<"$PATH"
/home/ek/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin

AWK est souvent utilisé pour analyser les enregistrements dans des champs séparés, mais il n'y a pas besoin de cela juste pour construire une liste de noms de répertoires.

Cela fonctionne même pour les entrées contenant des blancs (espaces et tabulations), voire plusieurs blancs consécutifs :

ek@Io:~$ awk 'BEGIN{RS=":"} {print $0}' <<<$'ab\t\t c:de    fg:h'
ab               c
de    fg
h

C'est-à-dire, à moins que vous ne fassiez en sorte que AWK reconstruire l'enregistrement (voir ci-dessous), il n'y a aucun problème à avoir des espaces ou des tabulations (les séparateurs de champs par défaut) dans la saisie. Votre PATH ne contient probablement pas d'espaces sur un système Ubuntu, mais si c'est le cas, cela fonctionnera quand même.


Il convient de mentionner, en passant, que la capacité d'AWK à interpréter un enregistrement comme une collection de champs devient utile pour le problème connexe de la construction d'une table d'annuaire composants :

ek@Io:~$ awk -F/ 'BEGIN{RS=":"; OFS="\t"} {$1=$1; print $0}' <<<"$PATH"
        home    ek      bin
        usr     local   sbin
        usr     local   bin
        usr     sbin
        usr     bin
        sbin
        bin
        usr     games
        usr     local   games
        snap    bin

Les curieux $1=$1 sert à forcer AWK pour reconstruire le dossier .

(Ceci est probablement plus utile pour les cas où un traitement supplémentaire doit être effectué sur les composants, que pour l'exemple exact montré de la simple impression du tableau).

1voto

David Fetter Points 11
jq -Rr 'gsub(":";"\n")' <<<$PATH

0voto

Aaron Hall Points 1018

Comment afficher séparément les chemins dans $PATH

Ce sont les méthodes que je préfère, en fonction de mes cas d'utilisation respectifs et de mes préoccupations en matière de compatibilité et d'utilisation des ressources.

tr

Tout d'abord, si vous avez besoin d'une solution rapide, facile à retenir et lisible, il suffit d'utiliser l'écho suivant PATH et l'envoyer à traduire ( tr ) pour transformer les deux-points en nouvelles lignes :

echo $PATH | tr : "\n"

Il a l'inconvénient d'utiliser deux processus à cause du pipe, mais si nous ne faisons que pirater dans un terminal, est-ce que cela nous intéresse vraiment ?

L'expansion du paramètre Shell de Bash

Si vous voulez une solution assez permanente dans votre .bashrc pour une utilisation interactive, vous pouvez aliaser la commande suivante en path mais la lisibilité de cette solution est discutable :

alias path="echo \"${PATH//:/$'\n'}\""

Si le motif commence par '/', toutes les correspondances du motif sont remplacées par une chaîne de caractères. Normalement, seule la première correspondance est remplacée.

La commande ci-dessus remplace les deux-points par des nouvelles lignes en utilisant la fonction de Bash ShellExpansion de paramètre :

${parameter/pattern/string}

Pour l'expliquer :

          # v--v---------delimiters, a'la sed
echo "${PATH//:/$'\n'}"
          #  ^^ ^^^^^----string, $ required to get newline character.
          #   \----------pattern, / required to substitute for *every* :.

Bonne chance pour s'en souvenir quand vous faites du piratage en ligne de commande, si vous ne l'avez pas aliasé, cependant.

IFS, testé en Bash et Dash

Alternativement, une approche assez cross-compatible, lisible et compréhensible qui ne repose sur rien d'autre que le Shell est d'utiliser la fonction suivante (je suggère dans votre .bashrc .)

La fonction suivante fait temporairement du séparateur de champ interne (ou d'entrée) (IFS) un deux-points, et lorsqu'un tableau est donné à printf il s'exécute jusqu'à ce que le tableau soit épuisé :

path () {
    local IFS=:
    printf "%s\n" ${PATH}
    }

Cette méthode de création de fonctions , IFS et printf sont fournis par Posix, et devraient donc fonctionner dans la plupart des shells de type Posix (en particulier Dash, qu'Ubuntu alias habituellement comme sh ).

Python

Faut-il utiliser Python pour cela ? C'est possible. Voici la commande Python la plus courte à laquelle je pense pour cela :

python -c "print('\n'.join('${PATH}'.split(':')))"

ou Python 3 seulement (et peut-être plus lisible ?) :

python3 -c "print(*'${PATH}'.split(':'), sep='\n')"

Elles devraient également fonctionner dans tout environnement Shell habituel, pour autant que vous disposiez de Python.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X