Если вы можете использовать bash
, есть нет необходимости использовать awk
: read
и shell parameter expansion не могут быть объединены, чтобы решить вашу проблему:
while read -r name rest; do
# Drop the '= ' part, if present.
[[ $rest == '= '* ]] && value=${rest:2} || value=$rest
# $value now contains the line's value,
# but *including* any enclosing ' chars, if any.
# Assuming that there are no *embedded* ' chars., you can remove them
# as follows:
value=${value//\'/}
done < parameters.txt
read
по умолчанию также разбивает строку на поля пробелами, как awk
, но в отличие от awk
он имеет возможность назначить остаток линии к Название переменной, а именно последний один, если меньше переменных, чем полей найдены указаны;
read
-r
вариант, как правило, стоит указать, чтобы избежать неожиданной интерпретации символов \
. на входе.
Как для попытки решения:
awk
не знает о цитировании на входе - по умолчанию он разбивает вход на поля пробелами, независимо от кавычек.
Таким образом, строка, такая как 'Hello World'
, просто разбита на поля 'Hello
и World'
.
Однако в вашем случае вы можете разделить каждую входную линию на ее ключ и значение с помощью тщательно созданного значения FS (FS - это разделитель полей ввода, который также можно установить с помощью опции -F
, а команда снова принимает bash
, на этот раз для использования <(...)
, так называемой process substitution и $'...'
, ANSI C-quoted string):
while IFS= read -r value; do
# Work with $value...
done < <(awk -F$'^[[:alnum:]]+ (=)?\'?|\'' '{ print $2 }' parameters.txt)
Снова предположение, что значения не содержат встроенных'
экземпляров.
Разделитель регулярное выражение $'^[[:alnum:]]+ (=)?\'?|\''
разбивает каждую строку так, чтобы $2
, 2-е поле, содержит значение, раздели ограждающих '
символов., Если таковые имеются.
xargs
является редким исключением среди стандартных утилит в том, что он делает понять одно- и строк в двойных кавычках (еще и без поддержки встроенных кавычек).
Таким образом, вы можете воспользоваться xargs
'способности неявно отогнать ограждающие кавычки, когда он передает аргументы в указанную команду, которая по умолчанию echo
(опять-таки предполагает bash
):
while read -r name rest; do
# Drop the '= ' part, if present.
[[ $rest == '= '* ]] && value=${rest:2} || value=$rest
# $value now contains the line's value, strippe of any enclosing
# single quotes by `xargs`.
done < <(xargs -L1 < parameters.txt)
xargs -L1
один процесс (1
) (-L
) одновременно и неявно вызывает echo
со всеми токенами, найденными в каждой строке, с любыми закрывающими кавычками, удаленными из отдельных токенов.
Двойное цитирование переменной должно исправить это. т. е. «$ p» –
Как работает 'example.conf'? Вам нужен код, который может обрабатывать форматы _both_ - с или без '=' между ключом и значением? – mklement0
@JacobH: Несмотря на то, что всегда полезно перекодировать ссылки на переменные в POSIX-подобном программировании (если вы специально не хотите разделить слово и глобусы), это не решит проблему. – mklement0