Variation sur votre approche python:python -c 'import sys;print sys.argv[1].replace(":","\n")' $PATH
Sergiy Kolodyazhnyy
Une autre variante de Python, un peu hacky: python -c "print r'$PATH'.replace(':', '\n')"(utilisation d'une chaîne brute en cas de barres obliques inverses)
wjandrea
3
trtravaillé pour moi (sur mac, d'ailleurs). Merci.
Mike S.
Pour ceux qui, comme moi, veulent l'ajouter à la leur .bash_profile, ajoutez la comme suit:alias path='tr ":" "\n" <<< "$PATH"'
Cette opération remplace toutes :dans $PATHpar un saut de ligne ( \n) et imprime le résultat. Le contenu de $PATHreste inchangé.
Si vous souhaitez uniquement remplacer le premier :, supprimez la deuxième barre oblique:echo -e "${PATH/:/\n}"
Comment s'appelle ce genre d'opération? C'est semblable à sed mais ce n'est pas sed. Quel est le nom afin que je puisse rechercher sur le Web pour plus d'informations à ce sujet.
Tulains Córdova
3
Suivez le lien (Expansion des paramètres) dans ma réponse et faites défiler jusqu'à la dernière seconde section intitulée:${parameter/pattern/string}
Cyrus
27
Utiliser IFS:
(set-f; IFS=:; printf "%s\n" $PATH)
IFScontient les caractères sur lesquels bash scinde, donc un IFSavec :make fait scinder le développement de $PATHon :. printfboucle les arguments sur la chaîne de format jusqu'à ce qu'ils soient épuisés. Nous devons désactiver la fonction Globbing (extension de caractères génériques) set -fafin que les caractères génériques dans les noms de répertoires PATH ne soient pas développés.
une variation à ce sujet, telle que echo $PATH | xargs -n1 -d: echoredondante ou peu importe?
Sergiy Kolodyazhnyy
@Serg echo $PATH | xargs -n1 -d: fera la même chose pour vous, mais vous utiliserez un shell supplémentaire. Le premier évaluera echo $PATHet dirigera la sortie vers le prochain shell pour faire le reste.
Souravc
7
Voici l'équivalent en Go:
$ cat path.go
package main
import ("fmt""os""strings")
func main(){for _, p := range strings.Split(os.Getenv("PATH"),":"){
fmt.Println(p)}}
$ go run path.go
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin
/home/nathan/.local/bin
/home/nathan/go/bin
Voici quelques approches supplémentaires. J'utilise un PATHavec des répertoires contenant des barres obliques inverses, des espaces et même une nouvelle ligne pour montrer qu'ils doivent fonctionner avec n'importe quoi (sauf cutcelui qui échoue sur les nouvelles lignes):
$ echo "$PATH"/bin:usr/bin/:/usr/local/bin:/some\ horrible thing:/even
new lines
Cela -psignifie "imprimer chaque ligne d'entrée après l'application du script donné par -e". Le script utilise l'opérateur de substitution ( s/oldnew/) pour tout remplacer :par des nouvelles lignes.
$ perl -lne 'print for split /:/'<<<"$PATH"/bin
usr/bin//usr/local/bin
/some\ horrible thing
/even
new lines
Le -lajoute une nouvelle ligne à chaque printappel. Ici, le script scinde son entrée :, puis boucle sur chaque élément scindé et l’imprime.
Les -amarques perlse comportent comme ceci awk: il divisera chacune de ses lignes en entrée sur le caractère donné par -F(donc :, ici) et sauvegardera le résultat dans le tableau @F. Le $"est une variable Perl spéciale, le "séparateur de liste", dont la valeur est imprimée entre chaque élément d'une liste imprimée. Donc, le définir sur une nouvelle ligne fera print @listimprimer chaque élément de @listpuis une nouvelle ligne. Ici, nous l’utilisons pour imprimer @F.
Même idée que ci-dessus, un peu moins golfée. Au lieu de l’utiliser $", nous allons explicitement joininsérer le tableau avec des nouvelles lignes, puis l’imprimer.
Le -ofait d' grepimprimer uniquement la partie correspondante de chaque ligne, de sorte que chaque correspondance est imprimée sur une ligne distincte. Le -Ppermet PCRE (PCRE). La regex recherche des segments de non :( [^:]+) qui suivent le début de la ligne ( ^) ou un :caractère. Il \Ks’agit d’une astuce PCRE qui signifie "jeter tout élément correspondant avant ce point" et qui est utilisée ici pour éviter d’imprimer :aussi.
Et une cutsolution (celle-ci échoue sur les nouvelles lignes, mais peut traiter les barres obliques inverses et les espaces):
Les options utilisées permettent de -d:définir le délimiteur d'entrée sur :, -f 1-ce qui signifie d'imprimer tous les champs (du premier au dernier) et de --output-delimiter=$'\n'définir le délimiteur de sortie. Le $'\n'est cité ANSI C et est un moyen d'imprimer un caractère de nouvelle ligne dans la coquille.
Dans tous les exemples ci-dessus, j'utilise l' opérateur string ( <<<) de bash (et de certains autres shells ) pour transmettre une chaîne en tant qu'entrée à un programme. Donc command <<<"foo"est équivalent à echo -n "foo" | command. Notez que je cite toujours "$PATH", sans les guillemets, le shell aurait mangé le caractère de nouvelle ligne.
C'est ce qu'on appelle le golf . Le -0spécifie le séparateur d'enregistrement d'entrée en tant que nombre octal ou hexadécimal. C'est ce qui définit une "ligne" et sa valeur par défaut est \nun caractère de nouvelle ligne. Ici, nous mettons cela à un :qui est x3aen hexadécimal (essayez printf '\x3a\n'). Le -lfait trois choses. Tout d'abord, il supprime le séparateur d'enregistrement d'entrée ( $/) à la fin de chaque ligne (ce qui supprime effectivement le :here), et deuxièmement, il définit le séparateur d'enregistrement de sortie ( $\) sur la valeur octale ou hexadécimale qui lui est donnée ( 012is \n). Si $\est défini, il est ajouté à la fin de chaque printappel, ainsi une nouvelle ligne sera ajoutée à chacun print.
La -pevolonté p Rint chaque ligne d'entrée après l' application du script donné par -e. Ici, il n'y a pas de script car tout le travail est effectué avec l'option flags comme décrit ci-dessus!
Vos doublures en perl one ne sont pas assez obscures! Voici une version où il n'y a pas de code pour le commutateur -e pour exécuter parce que les autres gèrent tout commutateurs: perl -0x3a -l012 -pe '' <<<$PATH. Explanation: -0définit le séparateur d'enregistrement d'entrée (spécifié en notation hexadécimale / octale, x3A est un signe deux-points), -leffectue deux opérations: 1) il décompose le séparateur d'enregistrement d'entrée, 2) il définit le séparateur d'enregistrement de sortie s'il en existe un (en notation octale , 012 est une nouvelle ligne). Une -pboucle imprime la valeur de $ _, qui sera chaque ligne lue.
7stud
Notez également que vos exemples en utilisant -Fpeut éliminer les -aet -ndrapeaux, comme -F tourne ceux automatiquement: perl -F: -e 'print(join "\n", @F);' <<<$PATH. Voir perlrun . Beaux exemples.
7 au
@ 7stud wow, c'est vraiment génial, merci! Sans vergogne volé et ajouté à ma réponse (je suppose que cela ne vous dérange pas, n'hésitez pas à le poster comme réponse et je le supprimerai). Et merci pour l' -Finfo. Je l'utilise en -Fassociation avec -andes années, je n'ai jamais réalisé que l'un impliquait les autres. A propos, j’ai vu Serg parler de Code Golf , mais je pense que vous apprécieriez également Unix et Linux si vous aimez ce genre de chose.
terdon
Hey, merci. Une clarification à propos de cette déclaration: Enfin, -lajoute également le séparateur d'enregistrement de sortie donné à la fin de chaque appel d'impression. En fait, print ajoute toujours le séparateur d'enregistrement de sortie,, $/à la fin d'une chaîne - si le séparateur d'enregistrement de sortie est défini. Par défaut, c'est undef. Donc, le jeu est -ldéfini $/, ce qui oblige print à ajouter la nouvelle ligne à la fin de la chaîne.
7 au
Je suppose que cela ne vous dérange pas - Pas du tout. :)
7stud
6
La seule façon de ne pas avoir été mentionnée est la façon dont je l'utilise depuis des années:
echo $PATH | tr ":" "\n"
alors, dans votre .profile ou .bash_profile ou autre, vous pouvez ajouter:
Oui, mais j'aime bien la suggestion pour le pseudonyme.
7stud le
6
Dans cette réponse:
C
Python
Rubis
Awk alternative
1. C
Comme tous les langages de script ont déjà été utilisés, je vais utiliser C. Il est assez facile d’obtenir des variables d’environnement avec une get_env()fonction (voir la documentation de la bibliothèque GNU C ). Le reste est simplement une manipulation de personnage
Ruby ne vient pas avec Ubuntu par défaut, contrairement au compilateur C et à l'interpréteur Python, mais si jamais vous vous retrouviez à l'utiliser, la solution dans Ruby serait la suivante:
ruby -ne 'puts $_.split(":")'<<<"$PATH"
Comme suggéré par 7stud (Merci beaucoup!) Dans les commentaires , cela peut aussi être raccourci avec
Nous pouvons utiliser la split()fonction pour décomposer la ligne lue en tableau, et utiliser la for-eachboucle pour imprimer chaque élément sur une ligne séparée.
awk '{split($0,arr,":"); for(var in arr) print arr[var]}'<<< $PATH
Bel exemple de rubis. putsimprime automatiquement les éléments d'un tableau sur des lignes séparées! Vous pouvez également faire en sorte que les commutateurs fassent le fractionnement: ruby -F: -ane 'puts $F' <<<$PATH Explication: -Fdéfinit $;le caractère spécifié, qui est le séparateur par défaut utilisé par String :: split ($; a une valeur par défaut de nil, qui sépare les espaces). -aappelle $ _. split, où $ _ est une ligne lue à l'aide de gets ()) et assigne le tableau résultant $F.
7stud le
@ 7stud hé, merci! :) Je ne savais pas qu'il y avait un -Fdrapeau - je viens juste de commencer avec Ruby, donc je fais les choses de façon légèrement rudimentaire.
Sergiy Kolodyazhnyy
Non, c'est obscur. Votre ligne est très lisible, et la clarté devrait l'emporter sur la brièveté à chaque fois.
7stud le
Hah. Je me suis un plus court: ruby -0072 -ne 'puts chomp' <<<$PATH. Explanation: -0définit le séparateur d'enregistrement d'entrée (spécifiez un caractère au format octal; 072 est un signe deux-points). Ruby emploie $ _ de manière similaire à Perl. La méthode gets () (utilisée dans la -nboucle) définit $ _ sur la ligne en cours de lecture. Et chomp()sans argument, chomps $ _. J'aime toujours mieux le tien. :)
7stud le
@ 7stud en fait, celui que vous avez posté plus tôt, avec -Fflag, est plus court. Si vous faites echo "ruby -F: -ane 'puts $F' <<<$PATH" |wc -c cela, cela me dit que c'est 271 octets, mais celui avec un nombre octal est 276. C'est pour la commande entière, bien sûr, si nous considérons que seul le code lui puts $F- même est nettement plus court. :) Au fait, connaissez-vous Code Golf ? C'est le site pour les solutions de programmation de puzzles dans le plus petit nombre d'octets. Il y a une question liée à celle-ci: codegolf.stackexchange.com/q/96334/55572
Sergiy Kolodyazhnyy
4
Nous avons besoin de plus de Java!
public class GetPathByLine{
public static void main(String[] args){for(String p :System.getenv("PATH").split(":")){System.out.println(p);}}}
Enregistrez ceci dans GetPathByLine.javaet compilez en utilisant:
javac GetPathByLine.java
Courir avec:
java GetPathByLine
┌─[17:06:55]─[kazwolfe@BlackHawk]└──>~ $ cat GetPathByLine.java
public class GetPathByLine{
public static void main(String[] args){for(String p :System.getenv("PATH").split(":")){System.out.println(p);}}}┌─[17:06:58]─[kazwolfe@BlackHawk]└──>~ $ javac GetPathByLine.java
┌─[17:07:02]─[kazwolfe@BlackHawk]└──>~ $ java GetPathByLine/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin
Plus court awk:echo $PATH | awk '{gsub(/\:/,"\n");print}'
Sergiy Kolodyazhnyy
Je ne sais pas trop pourquoi vous vous inquiétez de fileinputpouvoir utiliser input:python3 -c 'print(*input().split(":"), sep="\n")' <<< "$PATH"
wjandrea
2
J'utilise les "Bash Path Functions" de Stephen Collyer (voir son article dans Linux Journal ). Cela me permet d'utiliser la "liste séparée par des 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 actuel en:
dirs="";for i in*;doif[-d $i ];then addpath -p dirs $i;fi;done
Shell Parameter Expansion - explique $ {paramètre / modèle / chaîne}. Si le modèle commence par '/', toutes les correspondances de modèle sont remplacées par une chaîne.
Nous avons donc:
un motif /: commençant par '/' pour remplacer toutes les correspondances
une chaîne $ '\ n' qui est citée avec la contraction $ 'anytext' pour traiter le symbole de nouvelle ligne (\ n).
Une autre méthode AWK consiste à traiter chaque répertoire comme un enregistrement séparé plutôt que comme un champ séparé .
awk 'BEGIN{RS=":"} {print $0}'<<<"$PATH"
Je trouve cette syntaxe particulièrement intuitive. Mais, si vous le souhaitez, vous pouvez le raccourcir en rendant l’ print $0implicite (c’est l’action par défaut, elle 1vaut true, elle est exécutée pour chaque ligne):
awk 'BEGIN{RS=":"} 1'<<<"$PATH"
Le séparateur d'enregistrement par défaut d'entrée et de sortie d'AWK est la nouvelle ligne (saut de ligne). En définissant le séparateur d’enregistrement d’entrée ( RS) sur :avant de lire l’entrée, AWK analyse automatiquement un séparateur deux-points $PATHdans ses noms de répertoire constitutent. AWK s'étend $0à chaque enregistrement entier, la nouvelle ligne reste le séparateur d'enregistrement de sortie et aucune boucle gsubn'est nécessaire.
AWK est souvent utilisé pour analyser des enregistrements dans des champs distincts, mais il n'est pas nécessaire de créer une liste de noms de répertoires.
Cela fonctionne même pour les entrées contenant des espaces (espaces et tabulations), voire plusieurs espaces consécutifs:
ek@Io:~$ awk 'BEGIN{RS=":"} {print $0}'<<<$'ab\t\t c:de fg:h'
ab c
de fg
h
Autrement dit, à moins que AWK reconstruise l’enregistrement (voir ci-dessous), il n’ya aucun problème à avoir des espaces ou des tabulations (les séparateurs de champs par défaut) dans l’entrée. Votre PATHprobablement ne contient pas d'espaces sur un système Ubuntu, mais si c'est le cas, cela fonctionnera toujours.
Il convient de noter, en guise de remarque, que la capacité d'AWK d'interpréter un enregistrement en tant que collection de champs devient utile pour le problème connexe de la construction d'une table de composants de répertoire :
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
(Ceci est probablement plus utile dans les cas où un traitement supplémentaire doit être effectué sur les composants, plutôt que dans l'exemple exact de la simple impression du tableau.)
Comment afficher les chemins dans $ PATH séparément
Ce sont mes méthodes préférées pour ce faire, en fonction de mes cas d'utilisation respectifs et de mes préoccupations concernant la compatibilité et l'utilisation des ressources.
tr
Tout d’abord, si vous avez besoin d’une solution rapide, facile à mémoriser et lisible, il suffit de lui envoyer un message d’écho PATHpour qu’elle traduise ( tr) afin de transformer les deux points en nouvelles lignes:
echo $PATH | tr :"\n"
Il y a l'inconvénient d'utiliser deux processus en raison de la canalisation, mais si nous ne faisons que pirater un terminal, en sommes-nous vraiment préoccupés?
Expansion des paramètres du shell de Bash
Si vous souhaitez une solution relativement permanente dans votre .bashrcutilisation interactive, vous pouvez aliaser la commande suivante path, mais la lisibilité de cette solution est discutable:
alias path="echo \"${PATH//:/$'\n'}\""
Si motif commence par '/', toutes les correspondances de motif sont remplacées par une chaîne. Normalement, seul le premier match est remplacé.
# v--v---------delimiters, a'la sed
echo "${PATH//:/$'\n'}"# ^^ ^^^^^----string, $ required to get newline character.# \----------pattern, / required to substitute for *every* :.
Bonne chance de vous en souvenir lorsque vous vous contentez de pirater la ligne de commande, si vous ne l'avez pas encore aliasée.
IFS, testé en bash et dash
Alternativement, une approche relativement compatible, lisible et compréhensible qui ne repose pas sur autre chose que le shell utilise la fonction suivante (je suggère dans votre .bashrc.)
La fonction suivante transforme temporairement le séparateur de champs interne (ou d'entrée) en deux points, et lorsqu'un tableau est attribué à printf, il s'exécute jusqu'à son épuisement:
path (){local IFS=:
printf "%s\n" ${PATH}}
Cette méthode de création de fonctions , IFSet printfsont fournis par posix, donc il devrait fonctionner dans la plupart posix comme des coquilles ( en particulier Dash, qui Ubuntu généralement alias comme sh).
Python
Devez-vous utiliser Python pour cela? Vous pourriez. C’est la commande Python la plus courte à laquelle je puisse penser:
Réponses:
Essayez
sed
:Ou
tr
:Ou
python
:Ici, tout ce qui précède remplacera toutes les occurrences de
:
avec de nouvelles lignes\n
.la source
python -c 'import sys;print sys.argv[1].replace(":","\n")' $PATH
python -c "print r'$PATH'.replace(':', '\n')"
(utilisation d'une chaîne brute en cas de barres obliques inverses)tr
travaillé pour moi (sur mac, d'ailleurs). Merci..bash_profile
, ajoutez la comme suit:alias path='tr ":" "\n" <<< "$PATH"'
Utilisez les paramètres de bash :
Cette opération remplace toutes
:
dans$PATH
par un saut de ligne (\n
) et imprime le résultat. Le contenu de$PATH
reste inchangé.Si vous souhaitez uniquement remplacer le premier
:
, supprimez la deuxième barre oblique:echo -e "${PATH/:/\n}"
la source
${parameter/pattern/string}
Utiliser IFS:
IFS
contient les caractères sur lesquels bash scinde, donc unIFS
avec:
make fait scinder le développement de$PATH
on:
.printf
boucle les arguments sur la chaîne de format jusqu'à ce qu'ils soient épuisés. Nous devons désactiver la fonction Globbing (extension de caractères génériques)set -f
afin que les caractères génériques dans les noms de répertoires PATH ne soient pas développés.la source
Utilisant
xargs
:De
man xargs
la source
echo $PATH | xargs -n1 -d: echo
redondante ou peu importe?echo $PATH | xargs -n1 -d:
fera la même chose pour vous, mais vous utiliserez un shell supplémentaire. Le premier évalueraecho $PATH
et dirigera la sortie vers le prochain shell pour faire le reste.Voici l'équivalent en Go:
la source
Voici quelques approches supplémentaires. J'utilise un
PATH
avec des répertoires contenant des barres obliques inverses, des espaces et même une nouvelle ligne pour montrer qu'ils doivent fonctionner avec n'importe quoi (saufcut
celui qui échoue sur les nouvelles lignes):Quelques manières de Perl:
Cela
-p
signifie "imprimer chaque ligne d'entrée après l'application du script donné par-e
". Le script utilise l'opérateur de substitution (s/oldnew/
) pour tout remplacer:
par des nouvelles lignes.Le
-l
ajoute une nouvelle ligne à chaqueprint
appel. Ici, le script scinde son entrée:
, puis boucle sur chaque élément scindé et l’imprime.Les
-a
marquesperl
se comportent comme ceciawk
: il divisera chacune de ses lignes en entrée sur le caractère donné par-F
(donc:
, ici) et sauvegardera le résultat dans le tableau@F
. Le$"
est une variable Perl spéciale, le "séparateur de liste", dont la valeur est imprimée entre chaque élément d'une liste imprimée. Donc, le définir sur une nouvelle ligne feraprint @list
imprimer chaque élément de@list
puis une nouvelle ligne. Ici, nous l’utilisons pour imprimer@F
.Même idée que ci-dessus, un peu moins golfée. Au lieu de l’utiliser
$"
, nous allons explicitementjoin
insérer le tableau avec des nouvelles lignes, puis l’imprimer.Simple
grep
avec la magie PCRE:Le
-o
fait d'grep
imprimer uniquement la partie correspondante de chaque ligne, de sorte que chaque correspondance est imprimée sur une ligne distincte. Le-P
permet PCRE (PCRE). La regex recherche des segments de non:
([^:]+
) qui suivent le début de la ligne (^
) ou un:
caractère. Il\K
s’agit d’une astuce PCRE qui signifie "jeter tout élément correspondant avant ce point" et qui est utilisée ici pour éviter d’imprimer:
aussi.Et une
cut
solution (celle-ci échoue sur les nouvelles lignes, mais peut traiter les barres obliques inverses et les espaces):Les options utilisées permettent de
-d:
définir le délimiteur d'entrée sur:
,-f 1-
ce qui signifie d'imprimer tous les champs (du premier au dernier) et de--output-delimiter=$'\n'
définir le délimiteur de sortie. Le$'\n'
est cité ANSI C et est un moyen d'imprimer un caractère de nouvelle ligne dans la coquille.Dans tous les exemples ci-dessus, j'utilise l' opérateur string (
<<<
) de bash (et de certains autres shells ) pour transmettre une chaîne en tant qu'entrée à un programme. Donccommand <<<"foo"
est équivalent àecho -n "foo" | command
. Notez que je cite toujours"$PATH"
, sans les guillemets, le shell aurait mangé le caractère de nouvelle ligne.@ 7stud a donné une autre approche dans les commentaires qu'il est trop bon de ne pas inclure:
C'est ce qu'on appelle le golf . Le
-0
spécifie le séparateur d'enregistrement d'entrée en tant que nombre octal ou hexadécimal. C'est ce qui définit une "ligne" et sa valeur par défaut est\n
un caractère de nouvelle ligne. Ici, nous mettons cela à un:
qui estx3a
en hexadécimal (essayezprintf '\x3a\n'
). Le-l
fait trois choses. Tout d'abord, il supprime le séparateur d'enregistrement d'entrée ($/
) à la fin de chaque ligne (ce qui supprime effectivement le:
here), et deuxièmement, il définit le séparateur d'enregistrement de sortie ($\
) sur la valeur octale ou hexadécimale qui lui est donnée (012
is\n
). Si$\
est défini, il est ajouté à la fin de chaqueprint
appel, ainsi une nouvelle ligne sera ajoutée à chacunprint
.La
-pe
volonté p Rint chaque ligne d'entrée après l' application du script donné par-e
. Ici, il n'y a pas de script car tout le travail est effectué avec l'option flags comme décrit ci-dessus!la source
perl -0x3a -l012 -pe '' <<<$PATH
. Explanation:-0
définit le séparateur d'enregistrement d'entrée (spécifié en notation hexadécimale / octale, x3A est un signe deux-points),-l
effectue deux opérations: 1) il décompose le séparateur d'enregistrement d'entrée, 2) il définit le séparateur d'enregistrement de sortie s'il en existe un (en notation octale , 012 est une nouvelle ligne). Une-p
boucle imprime la valeur de $ _, qui sera chaque ligne lue.-F
peut éliminer les-a
et-n
drapeaux, comme -F tourne ceux automatiquement:perl -F: -e 'print(join "\n", @F);' <<<$PATH
. Voir perlrun . Beaux exemples.-F
info. Je l'utilise en-F
association avec-an
des années, je n'ai jamais réalisé que l'un impliquait les autres. A propos, j’ai vu Serg parler de Code Golf , mais je pense que vous apprécieriez également Unix et Linux si vous aimez ce genre de chose.-l
ajoute également le séparateur d'enregistrement de sortie donné à la fin de chaque appel d'impression. En fait, print ajoute toujours le séparateur d'enregistrement de sortie,,$/
à la fin d'une chaîne - si le séparateur d'enregistrement de sortie est défini. Par défaut, c'est undef. Donc, le jeu est-l
défini$/
, ce qui oblige print à ajouter la nouvelle ligne à la fin de la chaîne.La seule façon de ne pas avoir été mentionnée est la façon dont je l'utilise depuis des années:
echo $PATH | tr ":" "\n"
alors, dans votre .profile ou .bash_profile ou autre, vous pouvez ajouter:
alias path='echo $PATH | tr ":" "\n"'
la source
Dans cette réponse:
1. C
Comme tous les langages de script ont déjà été utilisés, je vais utiliser C. Il est assez facile d’obtenir des variables d’environnement avec une
get_env()
fonction (voir la documentation de la bibliothèque GNU C ). Le reste est simplement une manipulation de personnage2. Python
Mais aussi parce que "pourquoi pas", voici la version alternative de Python via des arguments en ligne de commande
sys.argv
3. rubis
Ruby ne vient pas avec Ubuntu par défaut, contrairement au compilateur C et à l'interpréteur Python, mais si jamais vous vous retrouviez à l'utiliser, la solution dans Ruby serait la suivante:
Comme suggéré par 7stud (Merci beaucoup!) Dans les commentaires , cela peut aussi être raccourci avec
et de cette façon
4. Alternative awk
Nous pouvons utiliser la
split()
fonction pour décomposer la ligne lue en tableau, et utiliser lafor-each
boucle pour imprimer chaque élément sur une ligne séparée.la source
puts
imprime automatiquement les éléments d'un tableau sur des lignes séparées! Vous pouvez également faire en sorte que les commutateurs fassent le fractionnement:ruby -F: -ane 'puts $F' <<<$PATH
Explication:-F
définit$;
le caractère spécifié, qui est le séparateur par défaut utilisé par String :: split ($; a une valeur par défaut de nil, qui sépare les espaces).-a
appelle $ _. split, où $ _ est une ligne lue à l'aide de gets ()) et assigne le tableau résultant$F
.-F
drapeau - je viens juste de commencer avec Ruby, donc je fais les choses de façon légèrement rudimentaire.ruby -0072 -ne 'puts chomp' <<<$PATH
. Explanation:-0
définit le séparateur d'enregistrement d'entrée (spécifiez un caractère au format octal; 072 est un signe deux-points). Ruby emploie $ _ de manière similaire à Perl. La méthode gets () (utilisée dans la-n
boucle) définit $ _ sur la ligne en cours de lecture. Etchomp()
sans argument, chomps $ _. J'aime toujours mieux le tien. :)-F
flag, est plus court. Si vous faitesecho "ruby -F: -ane 'puts $F' <<<$PATH" |wc -c
cela, cela me dit que c'est 271 octets, mais celui avec un nombre octal est 276. C'est pour la commande entière, bien sûr, si nous considérons que seul le code luiputs $F
- même est nettement plus court. :) Au fait, connaissez-vous Code Golf ? C'est le site pour les solutions de programmation de puzzles dans le plus petit nombre d'octets. Il y a une question liée à celle-ci: codegolf.stackexchange.com/q/96334/55572Nous avons besoin de plus de Java!
Enregistrez ceci dans
GetPathByLine.java
et compilez en utilisant:Courir avec:
la source
python3 -c "import os; [print(p) for p in os.getenv('PATH').split(':')]"
À travers awk.
À travers le python.
Notez que l'indentation est très important en python.
la source
echo $PATH | awk '{gsub(/\:/,"\n");print}'
fileinput
pouvoir utiliserinput
:python3 -c 'print(*input().split(":"), sep="\n")' <<< "$PATH"
J'utilise les "Bash Path Functions" de Stephen Collyer (voir son article dans Linux Journal ). Cela me permet d'utiliser la "liste séparée par des 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 actuel en:
Ensuite,
listpath -p dirs
produit une liste.la source
Explication de la réponse @Cyrus
Remarques:
Citation ANSI-C - cela explique $ 'some \ ntext'
Shell Parameter Expansion - explique $ {paramètre / modèle / chaîne}. Si le modèle commence par '/', toutes les correspondances de modèle sont remplacées par une chaîne.
Nous avons donc:
la source
Une autre méthode AWK consiste à traiter chaque répertoire comme un enregistrement séparé plutôt que comme un champ séparé .
Je trouve cette syntaxe particulièrement intuitive. Mais, si vous le souhaitez, vous pouvez le raccourcir en rendant l’
print $0
implicite (c’est l’action par défaut, elle1
vaut true, elle est exécutée pour chaque ligne):Le séparateur d'enregistrement par défaut d'entrée et de sortie d'AWK est la nouvelle ligne (saut de ligne). En définissant le séparateur d’enregistrement d’entrée (
RS
) sur:
avant de lire l’entrée, AWK analyse automatiquement un séparateur deux-points$PATH
dans ses noms de répertoire constitutent. AWK s'étend$0
à chaque enregistrement entier, la nouvelle ligne reste le séparateur d'enregistrement de sortie et aucune bouclegsub
n'est nécessaire.AWK est souvent utilisé pour analyser des enregistrements dans des champs distincts, mais il n'est pas nécessaire de créer une liste de noms de répertoires.
Cela fonctionne même pour les entrées contenant des espaces (espaces et tabulations), voire plusieurs espaces consécutifs:
Autrement dit, à moins que AWK reconstruise l’enregistrement (voir ci-dessous), il n’ya aucun problème à avoir des espaces ou des tabulations (les séparateurs de champs par défaut) dans l’entrée. Votre
PATH
probablement ne contient pas d'espaces sur un système Ubuntu, mais si c'est le cas, cela fonctionnera toujours.Il convient de noter, en guise de remarque, que la capacité d'AWK d'interpréter un enregistrement en tant que collection de champs devient utile pour le problème connexe de la construction d'une table de composants de répertoire :
La
$1=$1
tâche curieuse sert à forcer AWK à reconstruire l'enregistrement .(Ceci est probablement plus utile dans les cas où un traitement supplémentaire doit être effectué sur les composants, plutôt que dans l'exemple exact de la simple impression du tableau.)
la source
la source
Ce sont mes méthodes préférées pour ce faire, en fonction de mes cas d'utilisation respectifs et de mes préoccupations concernant la compatibilité et l'utilisation des ressources.
tr
Tout d’abord, si vous avez besoin d’une solution rapide, facile à mémoriser et lisible, il suffit de lui envoyer un message d’écho
PATH
pour qu’elle traduise (tr
) afin de transformer les deux points en nouvelles lignes:Il y a l'inconvénient d'utiliser deux processus en raison de la canalisation, mais si nous ne faisons que pirater un terminal, en sommes-nous vraiment préoccupés?
Expansion des paramètres du shell de Bash
Si vous souhaitez une solution relativement permanente dans votre
.bashrc
utilisation interactive, vous pouvez aliaser la commande suivantepath
, mais la lisibilité de cette solution est discutable:La commande ci-dessus remplace les deux-points par des nouvelles lignes à l'aide de l' extension des paramètres de shell de Bash :
Pour l'expliquer:
Bonne chance de vous en souvenir lorsque vous vous contentez de pirater la ligne de commande, si vous ne l'avez pas encore aliasée.
IFS, testé en bash et dash
Alternativement, une approche relativement compatible, lisible et compréhensible qui ne repose pas sur autre chose que le shell utilise la fonction suivante (je suggère dans votre
.bashrc
.)La fonction suivante transforme temporairement le séparateur de champs interne (ou d'entrée) en deux points, et lorsqu'un tableau est attribué à
printf
, il s'exécute jusqu'à son épuisement:Cette méthode de création de fonctions ,
IFS
etprintf
sont fournis par posix, donc il devrait fonctionner dans la plupart posix comme des coquilles ( en particulier Dash, qui Ubuntu généralement alias commesh
).Python
Devez-vous utiliser Python pour cela? Vous pourriez. C’est la commande Python la plus courte à laquelle je puisse penser:
ou seulement Python 3 (et peut-être plus lisible?):
Celles-ci devraient également fonctionner dans n’importe quel environnement shell habituel, tant que vous avez Python.
la source
Cette solution est plus simple que les solutions Java , C , go and awk :
Voici une autre grande possibilité:
Cela nécessiterait l'installation de certaines dépendances:
la source