PS1 = '$ (pwd)', почему это работает и почему это отличается от PS1 = $ (pwd)

Основными инструментами для такого рода работы являются sed и awk . Они предназначены для чтения строки за строкой из конвейера или файла и их преобразования.

Пример решения sed:

  sed 's/.* time=\([0-9]*\) ms/\1/' pingoutput.txt 

Должен вывести:

  202
  206
  215

Разбивка с /.* time = \ ([0-9] * \) мс / \ 1 / :

s означает, что вы хотите выполнить команду подстановки. Команды замены имеют шаблон s / <шаблон для соответствия> / <шаблон замены> / .

<шаблон для сопоставления> равен . * Time = \ ([0-9] * \) мс

. - любой символ. * говорит, что любой символ может появляться ноль или более раз. Это должно использовать все символы до части строки time = .

Часть \ (\) определяет то, что называется группой. Все, что соответствует шаблону между круглыми скобками, будет отсортировано в группу с именем 1, поскольку в нашем шаблоне есть только одна группа.

Часть внутри \ (\) - это [0-9] * , что означает соответствие любому символу между символом 0 и символом 9 (все цифры), и снова * означает, что может быть ноль или более. Это будет соответствовать интересующему вас числу.

Наконец, у нас есть мс в конце, чтобы потреблять его из строки.

<шаблон замены> - это просто \ 1 ; это означает, что вы хотите заменить всю совпавшую строку тем, что было захвачено группой №1 в шаблоне соответствия.

Вы также можете сделать это с помощью awk ; Я рекомендую научиться пользоваться обоими инструментами.

Дополнение:

Чтобы отсортировать значение численно, вам необходимо передать результаты в поток с помощью символа '|' в инструмент сортировки. Но чтобы убедиться, что время отсортировано численно, вы хотите использовать sort -n , иначе вы можете получить странный порядок сортировки.

sed 's/.* time=\([0-9]*\) ms/\1/' pingoutput.txt | sort -n

Дальнейшее дополнение для поддержки десятичных чисел

sed 's/.* time=\([0-9]*\(\.[0-9]*\)\{0,1\}\) ms/\1/' pingoutput.txt | sort -n

Я добавил необязательную часть, описывающую десятичную часть числа в группе, которая была \ ([0-9] * \). Я добавил:

Anther подгруппа, которая может появляться только 0 или 1 раз, описываемая как \ (\) \ {0,1 \}, часть в {} первом числе является минимальным вхождением второго числа - максимумом. Шаблон внутри эта группа является \. [0-9] * причиной, по которой мы должны вставлять \ из '.' это иначе, как вы теперь знаете ». означает любой символ, поэтому для него разрешается только '.' вам нужно избежать его с помощью \

18
23.02.2017, 00:30
3 ответа

Когда вы просто присваиваете значение переменной, выражение $(...) оценивается, если оно не заключено в одинарные кавычки (или в обратную кавычку). Чтобы понять, попробуйте сравнить эти два выражения:

A=$(pwd)
echo "$A"
B='$(pwd)'
echo "$B"

Значение A немедленно становится строкой /home/yourusername, и очевидно, что не запоминается, откуда взялась эта строка, она остается такой же, даже если вы смените каталог. Значение B, однако, становится буквальной строкой $(pwd) без интерпретации.

Теперь в значении PS1 происходит нечто особенное: всякий раз, когда выводится приглашение, интерпретируются некоторые специальные конструкции, например, подстановка команды $(...) выполняется точно так же, как это произошло выше при присваивании переменной A. Очевидно, что если ваша PS1 содержит литеральную строку вашего домашнего каталога (как выше в случае с A), то она никак не может измениться. Но если он содержит строку $(pwd) (как выше с B), то она оценивается всякий раз, когда выводится приглашение, и, следовательно, отображается ваш реальный каталог.

31
27.01.2020, 19:45

Поскольку без кавычек, $(pwd) оценивается при установке PS1. С кавычками оценка $(pwd) откладывается до появления подсказки.

Без кавычек PS1 устанавливается в текущий каталог в момент установки PS1. С одинарными кавычками PS1 устанавливается на $(pwd), что означает, что он будет оценивать и печатать текущий каталог каждый раз, когда отображается подсказка.

7
27.01.2020, 19:45

В bash и zsh значение PS1 не используется в качестве приглашения как такового, оно подвергается некоторым расширениям. Правила отличаются для этих двух оболочек, но в обоих случаях одним из шагов является выполнение "долларовых" расширений (подстановка переменных, подстановка команд, арифметическая оценка) с тем же синтаксисом, что и в обычном синтаксисе оболочки ($VARIABLE, ${VARIABLE}, $(COMMAND) or `COMMAND`, $((EXPRESSION)), $[EXPRESSION]) .

  • В bash расширение доллара включено по умолчанию, но может быть отключено с помощью shopt -u promptvars.
  • В zsh расширение доллара по умолчанию выключено, но многие люди (и большинство конфигурационных фреймворков, которые вы найдете в Интернете) включают его с помощью setopt prompt_subst.

При включенном расширении доллара в подсказке, PS1='$(pwd)' устанавливает PS1 в 6-символьное значение $(pwd) и таким образом вызывает подстановку $(pwd) и, следовательно, выполнение команды pwd каждый раз, когда оболочка отображает новую подсказку. С другой стороны, PS1=$(pwd) устанавливает PS1 в текущий рабочий каталог оболочки. Если бы долларовое расширение было выключено, то PS1='$(pwd)' привел бы к тому, что подсказкой стала бы литеральная строка $(pwd).

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

  • В bash, с помощью обратного слеша, например \w, который сокращает ваш домашний каталог до ~ и может быть обрезан установкой PROMPT_DIRTRIM.
  • В zsh с помощью процентного символа, например %/ или %~ (%/ то же самое, что $PWD, %~ сокращает домашние каталоги), который может иметь настройки обрезки.
  • В любой из этих оболочек (и любой другой оболочке в стиле Bourne), $PWD эквивалентен $(pwd): вам не нужно запускать подпроцесс, чтобы получить текущий рабочий каталог.
15
27.01.2020, 19:45

Теги

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