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

Как только проблема появилась на моем компьютере только сейчас, я думаю, что у меня есть лучшее решение.

Перейдите к Accessories -> Password Щелкните правой кнопкой мыши папку «login». Выберите «Изменить пароль». Выберите «разблокировать» и введите новый пароль.

Таким образом, всплывающее окно никогда не возвращается.

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

13 ответов

Использовать расширение параметра bash:

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

51
ответ дан 23 May 2018 в 22:09
  • 1
    Я думаю, что это лучшее решение, потому что это сделано в pure bash. – ryanmjacobs 23 March 2015 в 02:43
  • 2
    @ryanmjacobs слегка любопытно: как вы думаете, что мое решение использует? : D – muru 23 March 2015 в 10:27
  • 3
    пожалуйста, объясните, как это работает. – Tulains Córdova 23 March 2015 в 17:40
  • 4
    @ user1598390: Это заменяет все : в $ PATH новой строкой (\n) и печатает результат. Содержание $ PATH остается неизменным. Если вы хотите заменить первую :, удалите вторую косую черту: echo -e "${PATH/:/\n}" – Cyrus 23 March 2015 в 23:05
  • 5
    Следуйте ссылке (Расширение параметров) в своем ответе и прокрутите страницу до последней второй секции: ${parameter/pattern/string} – Cyrus 23 March 2015 в 23:18

Использование IFS:

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

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

22
ответ дан 23 May 2018 в 22:09
  • 1
    Это правильно работает с обратными косыми чертами и пробелами! – heinrich5991 23 March 2015 в 16: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.
13
ответ дан 23 May 2018 в 22:09
  • 1
    изменились бы на это, такие как echo $PATH | xargs -n1 -d: echo были излишними или это не имело бы значения? – Sergiy Kolodyazhnyy 3 April 2015 в 10:59
  • 2
    @Serg echo $PATH | xargs -n1 -d: сделает то же самое для вас, но вы будете использовать еще одну оболочку. Первый будет оценивать echo $PATH и вывод трубы в следующую оболочку, чтобы сделать остальное. – souravc 7 April 2015 в 15:46

Вот эквивалент в 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
7
ответ дан 23 May 2018 в 22:09

Вот еще несколько подходов. Я использую 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 ]. [F24] является специальной переменной 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 печать только соответствующей части каждой строки, поэтому каждое соответствие печатается на отдельной строке. [F33] позволяет Perl Compatible Regular Expressions (PCRE). Регулярное выражение ищет отрезки не : ([^:]+), которые следуют либо в начале строки (^), либо в символе :. [F38] - это трюк PCRE, который означает «отбросить все, что соответствует до этой точки», и используется здесь, чтобы избежать печати :. И 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', который устанавливает разделитель вывода, нужный. [F45] является цитированием ANSI C и является способом печати символа новой строки в оболочке.

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

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

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

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

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

7
ответ дан 23 May 2018 в 22:09
  • 1
    Ваш perl один лайнер не достаточно неясен! Вот версия, где нет кода для запуска -e, потому что остальные переключатели обрабатывают все: perl -0x3a -l012 -pe '' <<<$PATH. Объяснение: -0 устанавливает разделитель входных записей (указанный в шестнадцатеричной / восьмеричной нотации, x3A - двоеточие), -l выполняет две функции: 1) он перебирает разделитель входных данных, 2) он устанавливает разделитель выходной записи, если один (в восьмеричной нотации 012 является новой строкой). Цикл -p печатает значение $ _, которое будет отображаться в каждой строке . – 7stud 14 January 2017 в 08:59
  • 2
    Также обратите внимание, что ваши примеры с использованием -F могут устранить флаги -a и -n, так как -F автоматически активирует их: perl -F: -e 'print(join "\n", @F);' <<<$PATH. См. perlrun . Хорошие примеры. – 7stud 14 January 2017 в 09:00
  • 3
    @ 7stud ничего себе, это действительно отчасти блестяще, спасибо! Бесстыдно украден и добавлен к моему ответу (я полагаю, вы не против, не стесняйтесь публиковать его как ответ самостоятельно, и я удалю его). И спасибо за информацию -F. Я использовал -F в сочетании с -an в течение многих лет, я никогда не понимал, что это подразумевает других. Кстати, я видел, что Серг упомянул Programming Puzzles & Code Golf , но я думаю, что вы также будете наслаждаться Unix & Linux , если вы в этом заняты. – terdon♦ 14 January 2017 в 16:46
  • 4
    Привет, спасибо. Одно разъяснение об этом утверждении: Наконец, -l также добавляет разделитель выходной записи, заданный в конце каждого вызова печати. ​​ На самом деле, печать всегда добавляет разделитель выходной записи $/ к конец строки - если задан разделитель выходной записи. По умолчанию это undef. Таким образом, -l jus устанавливает $/ и вызывает печать для добавления новой строки в конец строки. – 7stud 14 January 2017 в 17:26
  • 5
    Я предполагаю, что вы не возражаете - Совсем нет. :) – 7stud 14 January 2017 в 17:31

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

C Python Ruby Alternative 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([d for d in sys.argv[1].split(":")])' "$PATH"

3. Ruby

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

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

Как было предложено 7stud (Большое спасибо!) в документации GNU C Library , это также можно сократить с помощью

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
ответ дан 23 May 2018 в 22:09
  • 1
    Хороший рубиновый пример. puts автоматически печатает элементы массива на отдельных строках! Вы также можете сделать переключатели для разделения: ruby -F: -ane 'puts $F' <<<$PATH Объяснение: -F устанавливает $; в указанный символ, который является разделителем по умолчанию, используемым String :: split ($; имеет значение по умолчанию nil, которое разделяет в пробеле). -a вызывает $ _. split, где $ _ - это строка, считанная с использованием gets ()) и присваивает результирующий массив $F. – 7stud 14 January 2017 в 08:37
  • 2
    @ 7stud эй, спасибо! :) Не знал, что есть флаг -F - я только начинаю с Ruby, так что делаю вещи немного грубо. – Sergiy Kolodyazhnyy 14 January 2017 в 08:42
  • 3
    Нет, это неясно. Ваш один лайнер очень читабельен, и ясность должна вызывать краткость каждый раз. – 7stud 14 January 2017 в 08:43
  • 4
    Хах. Я понял более короткий: ruby -0072 -ne 'puts chomp' <<<$PATH. Объяснение: -0 устанавливает разделитель входных записей (укажите символ в восьмеричном формате, 072 - двоеточие). Ruby использует $ _ способами, подобными Perl. Метод gets () (используемый в цикле -n) устанавливает $ _ в текущую строку , которая читается. И chomp() без arg, chomps $ _. Я все еще люблю твоего. :) – 7stud 14 January 2017 в 15:26
  • 5
    @ 7stud на самом деле, тот, который вы опубликовали ранее, с флагом -F короче. Если вы делаете echo "ruby -F: -ane 'puts $F' <<<$PATH" |wc -c , который говорит мне, что это 271, байты, но один с восьмеричным номером - 276. Это для всей команды, конечно. Если мы рассмотрим только сам код puts $F, это явно короче. :) Кстати, вы знаете о Programming Puzzles & Code Golf ? Это сайт для решения головоломок программирования в кратчайшем количестве байтов. Есть вопрос, связанный с этим: codegolf.stackexchange.com/q/96334/55572 – Sergiy Kolodyazhnyy 14 January 2017 в 15:36

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

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

, поэтому в вашем .profile или. bash_profile или что-то еще, вы можете добавить:

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

5
ответ дан 23 May 2018 в 22:09

Через 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
ответ дан 23 May 2018 в 22:09

Нам нужно больше 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
3
ответ дан 23 May 2018 в 22:09

Я использую «Функции пути Bash Path» Стивена Коллиера (см. его статью в Журнале Linux). Это позволяет мне использовать «разделенный двоеточиями список» в качестве типа данных в программировании оболочки. Например, я могу создать список всех каталогов в текущем каталоге:

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

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

2
ответ дан 23 May 2018 в 22:09

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

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

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

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

Разделитель входных и выходных данных по умолчанию AWK - это новая строка (разрыв строки). Установив разделитель входных данных (RS) на : перед чтением ввода, AWK автоматически анализирует разграниченный двоеточием $PATH в его именах constitentent. 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 часто используется для (! d6)

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

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

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

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

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
ответ дан 23 May 2018 в 22:09

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

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

Примечания:

ANSI-C Quoting - он объясняет $ 'some \ ntext'

ANSI-C Quoting - объясняет $ {parameter / pattern / string}. Если шаблон начинается с '/', все совпадения шаблона заменяются строкой.

Итак, у нас есть:

шаблон /: которые начинаются с '/', чтобы заменить все соответствия строкой $ '\ n', которая цитируется с сокращением $ 'anytext' для обработки нового символа строки (\ n).
1
ответ дан 23 May 2018 в 22:09
[F1]
1
ответ дан 23 May 2018 в 22:09

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

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