echo не печатает разрывы строк в конце переменной [duplicate]

Интересно, что я столкнулся с тем, что у вас может быть группа захвата внутри группы, не участвующей в захвате. Посмотрите ниже регулярное выражение для соответствия веб-URL:

var parse_url_regex = /^(?:([A-Za-z]+):)(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/;

Введите строку url:

var url = "http://www.ora.com:80/goodparts?q#fragment";

Первая группа в моем регулярном выражении (?:([A-Za-z]+):) - это не захватывающая группа который соответствует схеме протокола и символу двоеточия :, т.е. http:, но когда я работал под кодом, я видел, что первый индекс возвращаемого массива содержал строку http, когда я думал, что http и двоеточие : оба не получат сообщения, поскольку они находятся внутри группы, не содержащей захвата.

console.debug(parse_url_regex.exec(url));

Я думал, что если первая группа (?:([A-Za-z]+):) - это не захватывающая группа, то почему она возвращает строку http в выходном массиве.

Итак, если вы заметили, что внутри группы, не содержащей захвата, есть вложенная группа ([A-Za-z]+). Эта вложенная группа ([A-Za-z]+) является группой захвата (не имеющей ?: в начале) сама по себе внутри группы, не захватывающей (?:([A-Za-z]+):). Вот почему текст http по-прежнему захватывается, но символ двоеточия :, который находится внутри группы не захвата, но вне группы захвата, не получает сообщения в выходном массиве.

55
задан Mat 3 March 2013 в 11:39
поделиться

2 ответа

Неперехватывающие символы новой строки не удаляются

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

Валидация :

$ a=$( df -H )
$ echo $a
Filesystem Size Used Avail Use% Mounted on /dev/sda3 276G 50G 213G 19% / udev 2.1G 4.1k 2.1G 1% /dev tmpfs 832M 820k 832M 1% /run none 5.3M 0 5.3M 0% /run/lock none 2.1G 320k 2.1G 1% /run/shm
$ echo "$a"
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda3       276G   50G  213G  19% /
udev            2.1G  4.1k  2.1G   1% /dev
tmpfs           832M  820k  832M   1% /run
none            5.3M     0  5.3M   0% /run/lock
none            2.1G  320k  2.1G   1% /run/shm
$ 

Удалены новые строки

Так как @ user4815162342 правильно указал , хотя новые строки в выходе не удаляются, trailing newlines удаляются с заменой команды. См. Эксперимент ниже:

$ a=$'test\n\n'
$ echo "$a"
test


$ b=$(echo "$a")
$ echo "$b"
test
$

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

Методы обхода

1. Добавить фиктивный символ

В этом случае, как упоминалось в @Scrutinizer, вы можете использовать следующее обходное решение:

$ a=$(printf 'test\n\n'; printf x); a=${a%x}
$ echo "$a"
test


$ 

Объяснение: Символ x равен добавляется к выходу (используя printf x) после строк новой строки. Поскольку новые строки больше не trailing , они не удаляются подстановкой команд. Следующий шаг - удалить x, который мы добавили, используя оператор % в ${a%x}. Теперь у нас есть исходный вывод со всеми новыми символами !!!

2. Чтение с использованием подстановки процесса

Вместо того, чтобы использовать подстановку команд для назначения вывода программы переменной, мы можем вместо этого использовать подстановку процесса для подачи вывода программы на read встроенная команда (кредит для @ormaaj). Замена процесса сохраняет все новые строки. Чтение вывода в переменную несколько сложно, но вы можете сделать это следующим образом:

$ IFS= read -rd '' var < <( printf 'test\n\n' ) 
$ echo "$var"
test


$ 

Объяснение:

  • Мы установили внутренний разделитель полей для команды чтения с нулевым значением, с IFS=. В противном случае read не назначил весь вывод var, а только первый токен.
  • Мы вызываем read с параметрами -rd ''. r предназначен для того, чтобы предотвратить обратную косую черту в качестве специального символа, а с помощью d '' установить разделитель на ничего, чтобы чтение читало весь вывод, а не только первую строку.

3. Чтение из трубы

Вместо того, чтобы использовать команду или замену процесса для назначения вывода программы переменной, мы можем вместо этого передать вывод программы команде read (кредит @ormaaj). Трубопровод также сохраняет все новые строки. Обратите внимание, однако, что на этот раз мы установили необязательное поведение оболочки lastpipe, используя встроенный shopt . Это необходимо, так что команда read выполняется в текущей среде оболочки. В противном случае переменная будет назначена в подоболочке, и она не будет доступна из остальной части скрипта.

$ cat test.sh 
#!/bin/bash
shopt -s lastpipe
printf "test\n\n" | IFS= read -rd '' var
echo "$var"
$ ./test.sh 
test


$
89
ответ дан user000001 28 August 2018 в 12:33
поделиться

Я пытался обвести голову вокруг этого, потому что я использовал bash для потоковой передачи в результате запуска интерпретатора на скрипте F #. После некоторых проб и ошибок это оказалось для решения проблемы:

$ cat fsi.ch
#!/bin/bash
echo "$(fsharpi --quiet --exec --nologo $1)"

$ fsi.ch messages.fsx
Welcome to my program. Choose from the menu:
new | show | remove

Предполагая, что вам нужно запустить терминальную программу. Надеюсь, это поможет.

0
ответ дан Alexander 28 August 2018 в 12:33
поделиться
Другие вопросы по тегам:

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