Я не могу понять, как перечислить различные пути в $PATH
по отдельности, чтобы они выглядели так:
/bin
/usr/bin
/usr/local/bin
и т. Д.
Кто-нибудь знает правильную переменную для этого?
Попробуйте sed
:
$ sed 's/:/\n/g' <<< "$PATH"
Или tr
:
$ tr ':' '\n' <<< "$PATH"
Или python
:
$ python2 -c "import os; print os.environ['PATH'].replace(':', '\n')"
Здесь все вышеупомянутое заменит всеми случаями :
с новыми строками \n
.
Вероятно, единственным путем, который не был упомянут, является способ, которым я использовал его в течение многих лет:
echo $PATH | tr ":" "\n"
так, в Вашем .profile или .bash_profile или что бы то ни было, можно добавить:
alias path='echo $PATH | tr ":" "\n"'
Через 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.
Используя 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.
Используйте удар Расширение Параметра :
echo "${PATH//:/ Это заменяет весь :
в $PATH
новой строкой (\n
) и печатает результат. Содержание $PATH
остается неизменным.
, Если Вы только хотите заменить первое :
, удалите вторую наклонную черту: echo -e "${PATH/:/\n}"
\n'}"
Это заменяет весь :
в $PATH
новой строкой (\n
) и печатает результат. Содержание $PATH
остается неизменным.
, Если Вы только хотите заменить первое :
, удалите вторую наклонную черту: echo -e "${PATH/:/\n}"
Я использую "Функции Пути Bash Stephen Collyer" (см. его статья в Журнале Linux). Это разрешает мне использовать разделенный список "двоеточия" в качестве типа данных в программировании оболочки. Например, я могу произвести список всех каталогов в текущем каталоге:
dirs="";for i in * ; do if [ -d $i ] ; then addpath -p dirs $i; fi; done
Затем listpath -p dirs
производит список.
Используя IFS:
(set -f; IFS=:; printf "%s\n" $PATH)
IFS
содержит символы, на которых удар делает разделение, таким образом, IFS
с :
заставляет удар разделить расширение $PATH
на :
. printf
циклы аргументы по строке формата, пока аргументы не исчерпываются. Мы должны отключить globbing (подстановочное расширение) использование set -f
так, чтобы подстановочные знаки в именах каталогов ПУТИ не становились расширенными.
Нам нужно больше 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
Так как все языки сценариев уже были взяты, я пойду с 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
Но также и потому что, "почему не", вот альтернативная версия Python через параметры командной строки sys.argv
python -c 'import sys; print "\n".join(sys.argv[1].split(":"))' "$PATH"
Ruby не идет с Ubuntu по умолчанию, в отличие от компилятора C и интерпретатора Python, но если бы Вы когда-нибудь используете его, решение в Ruby было бы этим:
ruby -ne 'puts $_.split(":")' <<< "$PATH"
Как предложено 7stud (Большое спасибо!) в комментариях это может также быть сокращено с
ruby -F: -ane 'puts $F' <<<$PATH
ruby -0072 -ne 'puts chomp' <<<$PATH
Мы можем использовать split()
функционируйте для повреждения по линии считанный в массив и использование for-each
цикл для распечатывания каждого объекта на отдельной строке.
awk '{split($0,arr,":"); for(var in arr) print arr[var]}' <<< $PATH
Вот эквивалент в Движении:
$ 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
Вот еще несколько подходов. Я использую 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
. Здесь нет никакого сценария, потому что вся работа сделана флагами опции, как описано выше!
Другой 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 восстановить запись.
(Это, вероятно, более полезно для случаев, где дополнительная обработка должна быть сделана на компонентах, чем для точного примера, показанного простой печати таблицы.)
Это решение просто, чем 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
Как отобразить пути в $PATH отдельно
Это мои предпочтительные способы сделать это на основе моих соответствующих примеров использования и опасений по поводу совместимости и использования ресурсов.
tr
Во-первых, если Вам нужны быстрое, легкое, чтобы помнить, и читаемое решение, просто отозваться эхом PATH
и передайте его по каналу для перевода (tr
) превратить двоеточия в новые строки:
echo $PATH | tr : "\n"
Это имеет оборотную сторону использования двух процессов из-за канала, но если мы просто взламываем в терминале, мы действительно заботимся об этом?
Если Вы хотите довольно постоянное решение в Вашем .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* :.
Удача помня это, когда Вы просто взламываете на командной строке, если Вы не исказили ее, все же.
С другой стороны, довольно перекрестный совместимый, читаемый, и понятный подход, который ни на что не полагается кроме оболочки, является использованием следующая функция (я предлагаю в Вашем .bashrc
.)
Следующая функция временно делает Внутреннее (или Вход) Разделителем полей (IFS) двоеточие, и когда массиву дают printf
, это выполняется, пока массив не израсходован:
path () {
local IFS=:
printf "%s\n" ${PATH}
}
Этот метод функционального создания, IFS
, и printf
предусмотрены posix, таким образом, он должен работать в большинстве подобных posix оболочек (особенно Тире, которого Ubuntu обычно искажает как sh
).
Необходимо ли использовать Python для этого? Вы могли. Это - самая короткая команда Python, о которой я могу думать для этого:
python -c "print('\n'.join('${PATH}'.split(':')))"
или Python 3 только (и возможно более читаемый?):
python3 -c "print(*'${PATH}'.split(':'), sep='\n')"
Они должны работать в любой обычной среде оболочки также, пока у Вас есть Python.
Объяснение ответа @Cyrus
echo "${PATH//:/ Примечания:
ANSI-C, Заключающий в кавычки - это объясняет расширение 'some\ntext'
Shell Параметра $ - это объясняет $ {параметр/шаблон/строка}, Если шаблон начинается с †/’, все соответствия шаблона заменяются строкой.
, Таким образом, мы имеем:
- шаблон /: , которые начинают с '/' заменять все соответствия
- строка $ '\n' , который заключается в кавычки с $ 'anytext' сокращение для обработки символа новой строки (\n).
\n'}"
Примечания:
ANSI-C, Заключающий в кавычки - это объясняет расширение 'some\ntext'
Shell Параметра $ - это объясняет $ {параметр/шаблон/строка}, Если шаблон начинается с †/’, все соответствия шаблона заменяются строкой.
, Таким образом, мы имеем: