Как отобразить пути в $ PATH отдельно

Я не могу понять, как перечислить различные пути в $PATH по отдельности, чтобы они выглядели так:

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

и т. Д.

Кто-нибудь знает правильную переменную для этого?

46
задан 31 March 2015 в 21:33

16 ответов

Попробуйте sed:

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

Или tr:

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

Или python:

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

Здесь все вышеупомянутое заменит всеми случаями : с новыми строками \n.

53
ответ дан 31 March 2015 в 21:33

Вероятно, единственным путем, который не был упомянут, является способ, которым я использовал его в течение многих лет:

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

так, в Вашем .profile или .bash_profile или что бы то ни было, можно добавить:

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

5
ответ дан 31 March 2015 в 21:33

Через awk.

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

Через Python.

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

Примечание, что Добавление отступа очень важно в Python.

3
ответ дан 31 March 2015 в 21:33

Используя xargs:

xargs -n1 -d: <<< $PATH

От man xargs

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

 -d delim
          Input  items  are terminated by the specified character.
14
ответ дан 31 March 2015 в 21:33

Используйте удар Расширение Параметра :

echo "${PATH//:/ 

Это заменяет весь : в $PATH новой строкой (\n) и печатает результат. Содержание $PATH остается неизменным.
, Если Вы только хотите заменить первое :, удалите вторую наклонную черту: echo -e "${PATH/:/\n}"

\n'}"

Это заменяет весь : в $PATH новой строкой (\n) и печатает результат. Содержание $PATH остается неизменным.
, Если Вы только хотите заменить первое :, удалите вторую наклонную черту: echo -e "${PATH/:/\n}"

59
ответ дан 31 March 2015 в 21:33

Я использую "Функции Пути Bash Stephen Collyer" (см. его статья в Журнале Linux). Это разрешает мне использовать разделенный список "двоеточия" в качестве типа данных в программировании оболочки. Например, я могу произвести список всех каталогов в текущем каталоге:

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

Затем listpath -p dirs производит список.

2
ответ дан 31 March 2015 в 21:33

Используя IFS:

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

IFS содержит символы, на которых удар делает разделение, таким образом, IFS с : заставляет удар разделить расширение $PATH на :. printf циклы аргументы по строке формата, пока аргументы не исчерпываются. Мы должны отключить globbing (подстановочное расширение) использование set -f так, чтобы подстановочные знаки в именах каталогов ПУТИ не становились расширенными.

26
ответ дан 31 March 2015 в 21:33

Нам нужно больше Java!

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

Сохраните это к GetPathByLine.java, и использование компиляции:

javac GetPathByLine.java

Выполнение с:

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
4
ответ дан 1 April 2015 в 07:33

В этом ответе:

  1. C
  2. Python
  3. Ruby
  4. Альтернатива awk

1. C

Так как все языки сценариев уже были взяты, я пойду с C. Довольно легко получить переменные среды с get_env() функция (см. GNU C документация Библиотеки). Остальное - просто символьное управление

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

Но также и потому что, "почему не", вот альтернативная версия Python через параметры командной строки sys.argv

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

3. Ruby

Ruby не идет с Ubuntu по умолчанию, в отличие от компилятора C и интерпретатора Python, но если бы Вы когда-нибудь используете его, решение в Ruby было бы этим:

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

Как предложено 7stud (Большое спасибо!) в комментариях это может также быть сокращено с

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

и этот путь

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

4. Альтернатива awk

Мы можем использовать split() функционируйте для повреждения по линии считанный в массив и использование for-each цикл для распечатывания каждого объекта на отдельной строке.

awk '{split($0,arr,":"); for(var in arr) print arr[var]}' <<< $PATH
6
ответ дан 1 April 2015 в 07:33

Вот эквивалент в Движении:

$ 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
7
ответ дан 1 April 2015 в 07:33

Вот еще несколько подходов. Я использую a PATH с каталогами, содержащими обратные косые черты, пробелы и даже новую строку, чтобы показать, что они должны работать с чем-либо (кроме cut тот, который перестал работать на новых строках):

$ echo "$PATH"
/bin:usr/bin/:/usr/local/bin:/some\ horrible thing:/even 
new lines
  • Некоторый Perl пути:

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

    -p означает, "печатают каждую входную строку после применения сценария, данного -e". Сценарий использует оператор замены (s/oldnew/) заменять все : с новыми строками.

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

    -l добавляет новая строка к каждому print звонить. Здесь, сценарий разделяет свой вход на : и затем циклы по каждому элементу разделения и печати это.

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

    -a делает perl ведите себя как awk: это разделит каждую из своих входных строк на символе, данном -F (так :, здесь), и сохраняют результат в массиве @F. $" специальная переменная Perl, "разделитель элементов списка", значение которого печатается между каждым элементом печатного списка. Так установка его к новой строке сделает print @list распечатайте каждый элемент @list и затем новая строка. Здесь, мы используем его для печати @F.

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

    Та же идея как выше, просто менее игравший в гольф. Вместо использования $", мы явно joinлуг массив с новыми строками и затем печатью.

  • Простой grep с волшебством PCRE:

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

    -o делает grep распечатайте только часть соответствия каждой строки, таким образом, каждое соответствие печатается на отдельной строке. -P включает Perl совместимые регулярные выражения (PCRE). regex ищет фрагменты не -: ([^:]+) это следует за любым начало строки (^) или a : символ. \K прием PCRE, который означает "отбрасывание что-либо подобранное перед этой точкой" и используется здесь, чтобы не печатать : также.

  • И a cut решение (эти сбои на новых строках, но может иметь дело с обратными косыми чертами и пробелами):

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

    Используемые опции -d: который устанавливает входной разделитель на :, -f 1- что означает, печатают все поля (от 1-го в конец) и --output-delimiter=$'\n' который устанавливает, ну, в общем, выходной разделитель. $'\n' ANSI C заключение в кавычки и способ распечатать символ новой строки в оболочке.

Во всех вышеупомянутых примерах я использую удар (и некоторые другие оболочки) здесь представляют в виде строки (<<<) оператор для передачи строки как входа к программе. Так command <<<"foo" эквивалентно echo -n "foo" | command. Обратите внимание, что я всегда заключаю в кавычки "$PATH", без кавычек оболочка съела бы символ новой строки.


@7stud дал другой подход в комментариях, которые это просто слишком хорошо для не включения:

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

Это - то, что известно как игра в гольф. -0 указывает входной разделитель записей как восьмеричное или шестнадцатеричное число. Это - то, что определяет "строку", и ее значение по умолчанию \n, символ новой строки. Здесь, мы устанавливаем его на a : который является x3a в шестнадцатеричном числе (попытка printf '\x3a\n'). -l делает три вещи. Сначала это удаляет входной разделитель записей ($/) от конца каждой строки — эффективно удаление : здесь — и во-вторых, это устанавливает выходной разделитель записей ($\) к любому восьмеричному или шестнадцатеричному значению это дано (012 \n). Если $\ определяется, это добавляется в конец каждого print звоните, таким образом, это приведет к новой строке, добавленной каждому print.

-pe распечатает каждую входную строку после применения сценария, данного -e. Здесь нет никакого сценария, потому что вся работа сделана флагами опции, как описано выше!

7
ответ дан 1 April 2015 в 07:33

Другой AWK путь должен рассматривать каждый каталог как отдельную запись, а не как отдельное поле.

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

Я нахожу тот синтаксис особенно интуитивным. Но, если Вам нравится, можно сократить его путем создания print $0 неявный (это - действие по умолчанию, и 1 оценивает к истинному, заставляя это быть сделанным для каждой строки):

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

Входной и выходной разделитель записей AWK по умолчанию является новой строкой (разрыв строки). Путем установки входного разделителя записей (RS) к : прежде, чем считать вход, AWK автоматически анализирует двоеточие-deliminated $PATH в его constitutent имена каталогов. AWK расширяется $0 к каждой целой записи новая строка остается выходным разделителем записей и никаким цикличным выполнением или gsub необходим.

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 часто используется для парсинга записей в отдельные поля, но нет никакой потребности в этом только для построения списка имен каталогов.

Это работает даже на вход, содержащий пробелы (пробелы и вкладки), даже несколько последовательных пробелов:

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

Таким образом, если Вы не заставляете AWK восстанавливать запись (см. ниже), это не проблема, чтобы иметь пробелы или вкладки (разделители полей по умолчанию) во входе. Ваш PATH вероятно, не содержит пробелы в системе Ubuntu, но если она сделает, то это будет все еще работать.


Это стоит упомянуть как примечание стороны, что способность AWK интерпретировать запись как набор полей становится полезной для связанной проблемы построения таблицы компонентов каталога:

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

Любопытное $1=$1 присвоение служит цели вынудить AWK восстановить запись.

(Это, вероятно, более полезно для случаев, где дополнительная обработка должна быть сделана на компонентах, чем для точного примера, показанного простой печати таблицы.)

1
ответ дан 1 April 2015 в 07:33

Это решение просто, чем Java, , C, идут и awk решения:

$ LPATH=$PATH wine cmd /c echo %LPATH::= 

Вот другая большая возможность:

$ 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

Это потребовало бы, чтобы были установлены некоторые зависимости:

sudo apt-get install openjdk-8-jdk-headless bsh
\n'% 2> /dev/null /usr/local/bin /usr/local/sbin /usr/bin /usr/sbin

Вот другая большая возможность:

$ 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

Это потребовало бы, чтобы были установлены некоторые зависимости:

sudo apt-get install openjdk-8-jdk-headless bsh
0
ответ дан 3 August 2019 в 22:10

Как отобразить пути в $PATH отдельно

Это мои предпочтительные способы сделать это на основе моих соответствующих примеров использования и опасений по поводу совместимости и использования ресурсов.

tr

Во-первых, если Вам нужны быстрое, легкое, чтобы помнить, и читаемое решение, просто отозваться эхом PATH и передайте его по каналу для перевода (tr) превратить двоеточия в новые строки:

echo $PATH | tr : "\n"

Это имеет оборотную сторону использования двух процессов из-за канала, но если мы просто взламываем в терминале, мы действительно заботимся об этом?

Расширение параметра оболочки Bash

Если Вы хотите довольно постоянное решение в Вашем .bashrc для интерактивного использования можно исказить следующую команду к path, но удобочитаемость этого решения сомнительна:

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

Если шаблон начинается ‘/’, все соответствия шаблона заменяются строкой. Обычно только первое соответствие заменяется.

Вышеупомянутая команда заменяет двоеточием с новыми строками с помощью Расширения Параметра Shell Bash:

${parameter/pattern/string}

Объяснить это:

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

Удача помня это, когда Вы просто взламываете на командной строке, если Вы не исказили ее, все же.

IFS, протестированная в Bash и Тире

С другой стороны, довольно перекрестный совместимый, читаемый, и понятный подход, который ни на что не полагается кроме оболочки, является использованием следующая функция (я предлагаю в Вашем .bashrc.)

Следующая функция временно делает Внутреннее (или Вход) Разделителем полей (IFS) двоеточие, и когда массиву дают printf, это выполняется, пока массив не израсходован:

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

Этот метод функционального создания, IFS, и printf предусмотрены posix, таким образом, он должен работать в большинстве подобных posix оболочек (особенно Тире, которого Ubuntu обычно искажает как sh).

Python

Необходимо ли использовать Python для этого? Вы могли. Это - самая короткая команда Python, о которой я могу думать для этого:

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

или Python 3 только (и возможно более читаемый?):

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

Они должны работать в любой обычной среде оболочки также, пока у Вас есть Python.

0
ответ дан 3 August 2019 в 22:10
jq -Rr 'gsub(":";"\n")' <<<$PATH
1
ответ дан 3 August 2019 в 22:10

Объяснение ответа @Cyrus

echo "${PATH//:/ 

Примечания:

ANSI-C, Заключающий в кавычки - это объясняет расширение 'some\ntext'

Shell Параметра $ - это объясняет $ {параметр/шаблон/строка}, Если шаблон начинается с †˜/’, все соответствия шаблона заменяются строкой.

, Таким образом, мы имеем:

  1. шаблон /: , которые начинают с '/' заменять все соответствия
  2. строка $ '\n' , который заключается в кавычки с $ 'anytext' сокращение для обработки символа новой строки (\n).
\n'}"

Примечания:

ANSI-C, Заключающий в кавычки - это объясняет расширение 'some\ntext'

Shell Параметра $ - это объясняет $ {параметр/шаблон/строка}, Если шаблон начинается с †˜/’, все соответствия шаблона заменяются строкой.

, Таким образом, мы имеем:

  1. шаблон /: , которые начинают с '/' заменять все соответствия
  2. строка $ '\n' , который заключается в кавычки с $ 'anytext' сокращение для обработки символа новой строки (\n).
2
ответ дан 3 August 2019 в 22:10

Другие вопросы по тегам:

Похожие вопросы: