So zeigen Sie die Pfade in $ PATH separat an

45

Ich kann nicht herausfinden, wie die verschiedenen Pfade in $PATHgetrennt aufgeführt werden, so dass sie wie folgt aussehen:

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

usw.

Kennt jemand die richtige Variable dafür?

HankG
quelle
Jeder Pfad sollte bitte in einer separaten Zeile stehen
HankG
Was soll gedruckt werden, wenn Ihre Pfade Zeilenumbrüche enthalten?
Martijn
1
Und weil wir können!
Kaz Wolfe
Cross-Site-Duplikat unix.stackexchange.com/q/80151/85039
Sergiy Kolodyazhnyy

Antworten:

57

Versuchen Sie sed:

$ sed 's/:/\n/g' <<< "$PATH"

Oder tr:

$ tr ':' '\n' <<< "$PATH"

Oder python:

$ python2 -c "import os; print os.environ['PATH'].replace(':', '\n')"

Hier werden alle oben genannten Punkte :durch neue Zeilen ersetzt \n.

heemayl
quelle
Variation über Ihren Python-Ansatz:python -c 'import sys;print sys.argv[1].replace(":","\n")' $PATH
Sergiy Kolodyazhnyy
Eine andere Python-Variante, ein bisschen hacky: python -c "print r'$PATH'.replace(':', '\n')"(mit einem rohen String im Falle von Backslashes)
wjandrea
3
trarbeitete für mich (auf dem Mac, übrigens). Vielen Dank.
Mike S.
Für diejenigen, wie ich, die es hinzufügen möchten, fügen Sie .bash_profilees wie folgt:alias path='tr ":" "\n" <<< "$PATH"'
Mike S.
63

Verwenden Sie die Parametererweiterung von bash :

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

Dies ersetzt all :in $PATHdurch eine neue Zeile ( \n) und gibt das Ergebnis aus. Der Inhalt von $PATHbleibt unverändert.
Wenn Sie nur den ersten ersetzen möchten :, entfernen Sie den zweiten Schrägstrich:echo -e "${PATH/:/\n}"

Cyrus
quelle
3
Ich denke, dass dies die beste Lösung ist, weil es in purer Bash gemacht wird.
Ryanmjacobs
1
@ryanmjacobs milde neugierig: was denkst du nutzt meine lösung? : D
muru
1
Bitte erläutern Sie, wie es funktioniert.
Tulains Córdova
Wie heißt diese Operation? Es ist ähnlich wie sed, aber es ist nicht sed. Wie heißt es, damit ich im Internet nach weiteren Informationen suchen kann?
Tulains Córdova
3
Folgen Sie dem Link (Parameter Expansion) in meiner Antwort und scrollen Sie zum letzten zweiten Abschnitt mit dem Namen:${parameter/pattern/string}
Cyrus
27

Verwendung von IFS:

(set -f; IFS=:; printf "%s\n" $PATH)

IFSEnthält die Zeichen, für die die Bash-Aufteilung ausgeführt wird. IFSMit :der Option with wird die Aufteilung der Erweiterung von $PATHon ausgeführt :. printfSchleifen Sie die Argumente über die Formatzeichenfolge, bis die Argumente erschöpft sind. Wir müssen das Globbing (Platzhaltererweiterung) mit deaktivieren, set -fdamit Platzhalter in PATH-Verzeichnisnamen nicht erweitert werden.

muru
quelle
2
Dies funktioniert korrekt mit Backslashes und Leerzeichen!
heinrich5991
14

Verwenden von xargs:

xargs -n1 -d: <<< $PATH

Von man xargs

-n max-args
          Use  at  most  max-args  arguments per command line.

 -d delim
          Input  items  are terminated by the specified character.
souravc
quelle
Würde eine Variation davon, wie echo $PATH | xargs -n1 -d: echoredundant sein oder ist das egal?
Sergiy Kolodyazhnyy
@ Serg echo $PATH | xargs -n1 -d: wird das gleiche für Sie tun, aber Sie werden eine weitere Shell verwenden. Der erste Befehl wertet die echo $PATHAusgabe aus und leitet sie an die nächste Shell weiter, um den Rest zu erledigen.
Souravc
7

Hier ist das Äquivalent in 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
Nathan Osman
quelle
7

Hier sind einige weitere Ansätze. Ich benutze ein PATHmit Verzeichnissen, die Backslashes, Leerzeichen und sogar eine neue Zeile enthalten, um zu zeigen, dass sie mit irgendetwas funktionieren sollten (außer dem cut, das in Newlines fehlschlägt):

$ echo "$PATH"
/bin:usr/bin/:/usr/local/bin:/some\ horrible thing:/even 
new lines
  • Einige Perl-Möglichkeiten:

    $ perl -pe 's/:/\n/g' <<<"$PATH"
    /bin
    usr/bin/
    /usr/local/bin
    /some\ horrible thing
    /even 
    new lines
    

    Das -pbedeutet "drucke jede Eingabezeile nach Anwendung des von gegebenen Skripts -e". Das Skript verwendet den Substitutionsoperator ( s/oldnew/), um alle :Zeilen durch Zeilenumbrüche zu ersetzen .

    $ perl -lne 'print for split /:/' <<<"$PATH"
    /bin
    usr/bin/
    /usr/local/bin
    /some\ horrible thing
    /even 
    new lines
    

    Das -lfügt jedem printAnruf eine neue Leitung hinzu . Hier :teilt das Skript seine Eingabe auf und durchläuft dann jedes geteilte Element und druckt es aus.

    $ perl -F: -ane '$"="\n";print "@F"' <<<"$PATH"
    /bin
    usr/bin/
    /usr/local/bin
    /some\ horrible thing
    /even 
    new lines
    

    Die -aMarken perlverhalten sich wie awk: Sie teilen jede ihrer Eingabezeilen auf das von -F(also :hier) angegebene Zeichen und speichern das Ergebnis im Array @F. Das $"ist eine spezielle Perl-Variable, das "Listentrennzeichen", dessen Wert zwischen jedem Element einer gedruckten Liste gedruckt wird. Wenn Sie also eine neue Zeile festlegen, wird print @listjedes Element von @listund dann eine neue Zeile gedruckt. Hier verwenden wir es zum Drucken @F.

    $ perl -F: -ane 'print join "\n", @F' <<<"$PATH"
    /bin
    usr/bin/
    /usr/local/bin
    /some\ horrible thing
    /even 
    new lines
    

    Gleiche Idee wie oben, nur weniger Golf. Anstatt zu verwenden $", wird joindas Array explizit mit Zeilenumbrüchen versehen und dann gedruckt.

  • Einfach grepmit PCRE magic:

    $ grep -oP '(^|:)\K[^:]+' <<<"$PATH"
    /bin
    usr/bin/
    /usr/local/bin
    /some\ horrible thing
    /even 
    new lines
    

    Die -oMarken grepgedruckt werden nur den passenden Abschnitt jeder Linie, so dass jedes Spiel in einer separaten Zeile gedruckt wird. Das -Paktiviert Perl-kompatible reguläre Ausdrücke (PCRE). Der Regex sucht nach Abschnitten von non- :( [^:]+), die entweder auf den Anfang der Zeile ( ^) oder auf ein :Zeichen folgen . Das \Kist ein Trick PCRE das bedeutet „Discard etwas vor diesem Punkt angepasst“ und wird hier zu vermeiden , die den Druck :als auch.

  • Und eine cutLösung (diese schlägt in Zeilenumbrüchen fehl, kann aber mit Backslashes und Leerzeichen umgehen):

    $ cut -d: -f 1- --output-delimiter=$'\n' <<<"$PATH"
    /bin
    usr/bin/
    /usr/local/bin
    /some\ horrible thing
    /even 
    new lines
    

    Es werden folgende Optionen verwendet: -d:Setzt den Eingabebegrenzer auf :, -f 1-dh druckt alle Felder (vom 1. bis zum Ende) und --output-delimiter=$'\n'setzt den Ausgabebegrenzer. Das $'\n'ist ANSI C-Anführungszeichen und ist eine Möglichkeit, ein Zeilenumbruchzeichen in der Shell zu drucken.

In allen obigen Beispielen verwende ich den Operator string ( <<<) von bash (und einigen anderen Shells ), um einen String als Eingabe für ein Programm zu übergeben. Ist command <<<"foo"also gleichbedeutend mit echo -n "foo" | command. Beachten Sie, dass ich immer zitiere "$PATH", ohne die Anführungszeichen hätte die Shell das Zeilenumbruchszeichen gegessen.


@ 7stud gab einen anderen Ansatz in den Kommentaren an , der einfach zu gut ist, um ihn nicht einzuschließen :

$ perl -0x3a -l012 -pe '' <<<"$PATH"

Das nennt man Golfen . Das -0gibt das Eingabesatztrennzeichen als Oktal- oder Hexadezimalzahl an. Dies definiert eine "Linie" und ihr Standardwert ist \nein Zeilenumbruchzeichen. Hier sind wir es auf eine Einstellung , :die ist x3ain hex (Versuch printf '\x3a\n'). Das -lmacht drei Dinge. Zunächst das Eingangsdatensatztrennzeichen (entfernt $/) von dem Ende jeder Zeile effektiv Entfernen des :Hier und zweiten, den Ausgabesatz Separator (Sets $\), was auch immer Oktal oder Hexadezimalwert ihm gegeben wird ( 012ist \n). Wenn dies $\definiert ist, wird es am Ende jedes printAnrufs hinzugefügt , sodass an jeden eine neue Zeile angehängt wird print.

Der -peWille p rint jede Eingabezeile nach dem Skript von bestimmten Anwendung -e. Hier gibt es kein Skript, da die gesamte Arbeit mit den oben beschriebenen Options-Flags erledigt wird!

terdon
quelle
Ihre Perl-One-Liner sind nicht dunkel genug! Hier ist eine Version , wo es kein Code für den -en Schalter auszuführen , da die anderen Schalter alles im Griff: perl -0x3a -l012 -pe '' <<<$PATH. Erläuterung: Legt das Trennzeichen für Eingabedatensätze fest (in -0hexadezimaler / oktaler Schreibweise angegeben, x3A ist ein Doppelpunkt), -lführt zwei Aktionen aus: 1) Legt das Trennzeichen für Eingabedatensätze fest, 2) Legt das Trennzeichen für Ausgabedatensätze fest, wenn eines angegeben ist (in oktaler Schreibweise) , 012 ist ein Zeilenumbruch). Eine -pSchleife gibt den Wert von $ _ aus, der in jeder Zeile eingelesen wird.
7stud
Beachten Sie auch , dass Ihre Beispiele unter Verwendung -Fder kann beseitigen -aund -nFahnen, wie -F diejenigen , schaltet sich automatisch ein: perl -F: -e 'print(join "\n", @F);' <<<$PATH. Siehe perlrun . Schöne Beispiele.
7.
@ 7stud wow, das ist echt genial, danke! Schamlos gestohlen und zu meiner Antwort hinzugefügt (Ich nehme an, es macht Ihnen nichts aus, Sie können es gerne selbst als Antwort posten und ich werde es löschen). Und danke für die -FInfo. Ich benutze seit Jahren das -FKombinierte mit -an. Ich habe nie bemerkt, dass das eine das andere impliziert. Übrigens, ich habe gesehen, dass Serg Code Golf erwähnt hat , aber ich denke, dass Sie auch Unix und Linux mögen, wenn Sie sich für solche Dinge interessieren.
Terdon
Hey danke. Eine Klarstellung zu dieser Anweisung: Fügt schließlich -lauch das Trennzeichen für Ausgabesätze hinzu, das am Ende jedes Druckaufrufs angegeben wird. Tatsächlich fügt print das Trennzeichen für Ausgabedatensätze immer $/am Ende einer Zeichenfolge ein - wenn das Trennzeichen für Ausgabedatensätze definiert ist. Standardmäßig ist es undef. Also -lsetzt jus $/und das bewirkt, dass print die neue Zeile an das Ende der Zeichenkette anfügt.
7.
Ich nehme an, es macht Ihnen nichts aus - überhaupt nicht. :)
7stud
6

In dieser Antwort:

  1. C
  2. Python
  3. Rubin
  4. Alternative awk

1. C

Da alle Skriptsprachen bereits verwendet wurden, gehe ich zu C. Es ist ziemlich einfach, Umgebungsvariablen mit get_env()function zu erhalten (siehe GNU C Library-Dokumentation ). Der Rest ist einfach Zeichenmanipulation

bash-4.3$ cat get_path.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
    char *path = getenv("PATH");
    int length = strlen(path) -1;
    for(int i=0;i<=length;i++){
        if (path[i] == ':')
            path[i] = '\n';
        printf("%c",path[i]);
    }
    printf("\n");
    return 0;
}
bash-4.3$ gcc get_path.c
bash-4.3$ ./a.out 
/home/xieerqi/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin
/opt/microchip/xc16/v1.25/bin
/opt/microchip/xc32/v1.40/bin
/opt/microchip/xc8/v1.35/bin
/home/xieerqi/bin
/home/xieerqi/bin/sh

2. Python

Aber auch, weil "warum nicht", hier eine alternative Python-Version über Kommandozeilenargumente sys.argv

python -c 'import sys; print "\n".join(sys.argv[1].split(":"))' "$PATH"

3. Ruby

Ruby wird nicht standardmäßig mit Ubuntu geliefert, im Gegensatz zu C-Compiler und Python-Interpreter. Wenn Sie es jedoch jemals verwenden, lautet die Lösung in Ruby wie folgt:

ruby -ne 'puts $_.split(":")' <<< "$PATH"

Wie von 7stud (Vielen Dank!) In den Kommentaren vorgeschlagen , kann dies auch mit gekürzt werden

ruby -F: -ane 'puts $F' <<<$PATH

und so

ruby -0072 -ne 'puts chomp' <<<$PATH

4. Alternative awk

Wir können die split()Funktion verwenden, um die gelesene Zeile in ein Array aufzuteilen, und die for-eachSchleife verwenden, um jedes Element in einer separaten Zeile auszudrucken.

awk '{split($0,arr,":"); for(var in arr) print arr[var]}' <<< $PATH
Sergiy Kolodyazhnyy
quelle
1
Schönes Rubin Beispiel. putsdruckt die Elemente eines Arrays automatisch in separate Zeilen! Sie können auch festlegen, dass die Schalter die Aufteilung durchführen: ruby -F: -ane 'puts $F' <<<$PATH Erläuterung: -FWird $;auf das angegebene Zeichen festgelegt. Dies ist das von String :: split verwendete Standardtrennzeichen ($; hat den Standardwert nil, der auf Leerzeichen aufgeteilt wird). -aruft $ _. split auf, wobei $ _ eine mit gets ()) eingelesene Zeile ist und das resultierende Array zuweist $F.
7.
@ 7stud Hey, danke! :) Wusste nicht, dass es eine -FFlagge gibt - ich fange gerade mit Ruby an und mache die Dinge ein bisschen grob.
Sergiy Kolodyazhnyy
Nein, das ist dunkles Zeug. Ihr Einzeiler ist sehr gut lesbar und die Klarheit sollte jedes Mal die Kürze übertreffen.
7.
Hah Ich dachte , eine kürzere out: ruby -0072 -ne 'puts chomp' <<<$PATH. Erläuterung: -0Legt das Trennzeichen für Eingabesätze fest (geben Sie ein Zeichen im Oktalformat an; 072 ist ein Doppelpunkt). Ruby verwendet $ _ auf ähnliche Weise wie Perl. Die gets () -Methode (in der -nSchleife verwendet) setzt $ _ auf die aktuelle Zeile , die eingelesen wird. Und chomp()ohne ein Argument, chomps $ _. Ich mag deine immer noch besser. :)
7stud
@ 7stud Tatsächlich ist die, die Sie zuvor mit -Fflag gepostet haben, kürzer. Wenn Sie das tun echo "ruby -F: -ane 'puts $F' <<<$PATH" |wc -c , heißt das, dass es 271 Bytes sind, aber die mit der Oktalzahl ist 276. Das gilt natürlich für den gesamten Befehl. Wenn wir nur den Code selbst betrachten, puts $Fist dieser deutlich kürzer. :) Übrigens, kennen Sie Code Golf ? Es ist die Seite für Lösungen zum Programmieren von Rätseln in kürzester Anzahl von Bytes. Es gibt eine Frage zu dieser: codegolf.stackexchange.com/q/96334/55572
Sergiy Kolodyazhnyy
5

Wahrscheinlich ist der einzige Weg, der nicht erwähnt wurde, der Weg, den ich seit Jahren benutze:

echo $PATH | tr ":" "\n"

In Ihrem .profile oder .bash_profile oder was auch immer können Sie Folgendes hinzufügen:

alias path='echo $PATH | tr ":" "\n"'

Trottel
quelle
1
Diese Antwort erwähnte es bereits ..
heemayl
Ja, aber ich mag den Vorschlag für den Alias.
7.
4

Wir brauchen mehr Java!

public class GetPathByLine {
    public static void main(String[] args) {
        for (String p : System.getenv("PATH").split(":")) {
            System.out.println(p);
        }
    }
}

Speichern Sie dies in GetPathByLine.javaund kompilieren Sie es mit:

javac GetPathByLine.java

Laufen mit:

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
Kaz Wolfe
quelle
Wow das ist übertrieben. Sie können dies in einer Zeile in Python 3 tun:python3 -c "import os; [print(p) for p in os.getenv('PATH').split(':')]"
wjandrea
1
@ Wjandrea Das ist der Punkt! : D
Kaz Wolfe
3

Durch awk.

echo $PATH | awk -F: '{for(i=1;i<=NF;i++)print $i}'

Durch Python.

$ echo $PATH | python3 -c 'import fileinput
for line in fileinput.input():
    for i in line.split(":"):
        print(i)'

Beachten Sie, dass Einrückungen in Python sehr wichtig sind.

Avinash Raj
quelle
Kürzere echo $PATH | awk '{gsub(/\:/,"\n");print}'
Frist
Ich bin mir nicht sicher, warum Sie sich die Mühe machen, fileinputwenn Sie nur verwenden könnten input:python3 -c 'print(*input().split(":"), sep="\n")' <<< "$PATH"
wjandrea
2

Ich benutze Stephen Collyers "Bash Path Functions" (siehe seinen Artikel im Linux Journal ). Es erlaubt mir, die "durch Doppelpunkte getrennte Liste" als Datentyp in der Shell-Programmierung zu verwenden. Zum Beispiel kann ich eine Liste aller Verzeichnisse im aktuellen Verzeichnis erstellen, indem ich:

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

Dann listpath -p dirswird eine Liste erstellt.

Waltinator
quelle
2

Erklärung zur @ Cyrus-Antwort

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

Anmerkungen:

ANSI-C Quoting - erklärt $ 'some \ ntext'

Shell Parameter Expansion - erklärt $ {parameter / pattern / string}. Wenn pattern mit '/' beginnt, werden alle Übereinstimmungen von pattern durch string ersetzt.

Also haben wir:

  1. ein Muster /: das mit '/' beginnt, um alle Übereinstimmungen zu ersetzen
  2. ein String $ '\ n', der mit $ 'anytext' -Kontraktion in Anführungszeichen gesetzt wird, um das neue Liniensymbol (\ n) zu behandeln.
victorq10
quelle
1

Eine andere AWK-Methode besteht darin, jedes Verzeichnis als separaten Datensatz und nicht als separates Feld zu behandeln .

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

Ich finde diese Syntax besonders intuitiv. Wenn Sie möchten, können Sie es jedoch verkürzen, indem Sie das print $0implizite Element festlegen (dies ist die Standardaktion, 1die mit true ausgewertet wird und für jede Zeile ausgeführt wird):

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

Das standardmäßige Eingabe- und Ausgabesatztrennzeichen von AWK ist der Zeilenumbruch. Durch Setzen des Trennzeichens ( RS) für :Eingabedatensätze vor dem Lesen der Eingabe analysiert AWK automatisch einen durch Doppelpunkte getrennten Namen $PATHin den konstituierenden Verzeichnisnamen. AWK wird $0auf jeden vollständigen Datensatz erweitert, die neue Zeile bleibt das Trennzeichen für den Ausgabedatensatz , und es ist keine Schleife gsuberforderlich.

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 wird häufig zum Parsen von Datensätzen in separate Felder verwendet, es ist jedoch nicht erforderlich, lediglich eine Liste von Verzeichnisnamen zu erstellen.

Dies funktioniert auch für Eingaben mit Leerzeichen (Leerzeichen und Tabulatoren) und mehreren aufeinanderfolgenden Leerzeichen:

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

Das heißt, es sei denn, Sie veranlassen AWK , den Datensatz neu zu erstellen (siehe unten), ist es kein Problem, Leerzeichen oder Tabulatoren (die Standardfeldtrennzeichen) in der Eingabe zu haben. Ihr enthält PATHwahrscheinlich keine Leerzeichen auf einem Ubuntu-System, aber wenn dies der Fall ist, funktioniert dies immer noch.


Es ist erwähnenswert, als eine Randnotiz, dass AWK Fähigkeit eine Aufzeichnung als eine Sammlung von Feldern zu interpretieren wird , die für das damit verbundene Problem der Konstruktion eine Tabelle von Verzeichnis Komponenten :

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

Die merkwürdige $1=$1Aufgabe hat den Zweck, AWK zu zwingen , den Datensatz neu zu erstellen .

(Dies ist wahrscheinlich nützlicher für Fälle, in denen zusätzliche Verarbeitung für die Komponenten ausgeführt werden soll, als für das genaue gezeigte Beispiel des einfachen Druckens der Tabelle.)

Eliah Kagan
quelle
1
jq -Rr 'gsub(":";"\n")' <<<$PATH
David Fetter
quelle
0

So zeigen Sie die Pfade in $ PATH separat an

Dies sind meine bevorzugten Methoden, basierend auf meinen jeweiligen Anwendungsfällen und Bedenken hinsichtlich Kompatibilität und Ressourcennutzung.

tr

Wenn Sie eine schnelle, leicht zu merkende und lesbare Lösung benötigen, wiederholen Sie diese und leiten Sie PATHsie an translate ( tr) weiter , um die Doppelpunkte in Zeilenumbrüche umzuwandeln:

echo $PATH | tr : "\n"

Es hat den Nachteil, dass aufgrund der Pipe zwei Prozesse verwendet werden, aber wenn wir nur in ein Terminal hacken, interessiert uns das wirklich?

Bashs Shell-Parameter-Erweiterung

Wenn Sie eine relativ dauerhafte Lösung .bashrcfür die interaktive Verwendung wünschen , können Sie den folgenden Befehl als Alias ​​verwenden path, die Lesbarkeit dieser Lösung ist jedoch fraglich:

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

Wenn das Muster mit '/' beginnt, werden alle Übereinstimmungen des Musters durch eine Zeichenfolge ersetzt. Normalerweise wird nur die erste Übereinstimmung ersetzt.

Der obige Befehl ersetzt den Doppelpunkt mit Zeilenumbrüchen unter Verwendung der Shell-Parametererweiterung von Bash :

${parameter/pattern/string}

Um es zu erklären:

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

Viel Glück, wenn Sie sich daran erinnern, wenn Sie nur über die Befehlszeile hacken, wenn Sie es aber nicht geglättet haben.

IFS, getestet in Bash und Dash

Alternativ können Sie die folgende Funktion verwenden, wenn Sie einen ziemlich kompatiblen, lesbaren und verständlichen Ansatz verfolgen, der sich auf nichts anderes als die Shell stützt (ich schlage in Ihrem Beispiel vor .bashrc).

Die folgende Funktion macht das interne (oder Eingabe-) Feldtrennzeichen (IFS) vorübergehend zu einem Doppelpunkt, und wenn ein Array übergeben wird, printfwird es ausgeführt, bis das Array aufgebraucht ist:

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

Diese Methode der Funktion Schöpfung , IFSund printfsind für die von Posix vorgesehen, so dass es in den meisten Posix artigen Schalen funktionieren sollte (vor allem Dash, die Ubuntu in der Regel Aliase wie sh).

Python

Solltest du dafür Python verwenden? Du könntest. Dies ist der kürzeste Python-Befehl, den ich mir vorstellen kann:

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

oder nur Python 3 (und vielleicht besser lesbar?):

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

Diese sollten auch in jeder normalen Shell-Umgebung funktionieren, solange Sie Python haben.

Aaron Hall
quelle
0

Diese Lösung ist einfacher als die Java , C , go und awk- Lösungen:

$ LPATH=$PATH wine cmd /c echo %LPATH::=$'\n'% 2> /dev/null
/usr/local/bin
/usr/local/sbin
/usr/bin
/usr/sbin

Hier ist eine weitere großartige Möglichkeit:

$ jrunscript -classpath /usr/share/java/bsh.jar -e 'print(java.lang.System.getenv("PATH").replaceAll(":","\n"))'
/usr/local/bin
/usr/local/sbin
/usr/bin
/usr/sbin

Dazu müssten einige Abhängigkeiten installiert werden:

sudo apt-get install openjdk-8-jdk-headless bsh
Gungwald
quelle