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

Не так просто поддерживать localили нет. Существует множество вариаций синтаксиса и того, как это делается между оболочками, которые имеют ту или иную форму локальной области видимости.

Вот почему очень трудно придумать стандарт, который устраивал бы всех. См.http://austingroupbugs.net/bug_view_page.php?bug_id=767об усилиях POSIX в этом направлении.

локальная область видимости была впервые добавлена ​​в ksh в начале 80-х.

Синтаксис для объявления локальной переменной в функции был сtypeset:

function f {
  typeset var=value
  set -o noglob # also local to the function
 ...
}

(поддержка функций была добавлена ​​в оболочку Bourne позже, но с другим синтаксисом(f() commandkshдобавлена ​​поддержка и этой позже; оболочка Bourne никогда не имела локальной области видимости (, за исключением, конечно, подоболочек))

Встроенный AFAIK localбыл впервые добавлен в оболочку Almquist (, используемую в BSD, dash, busybox sh )в 1989 году, но работает значительно иначе, чем kshtypeset. Производные ashне поддерживают typesetв качестве псевдонима для local, но вы всегда можете определить его вручную.

bash и zsh добавили typesetс псевдонимом localв 1989 и 1991 годах соответственно.

ksh88 добавлен localв качестве недокументированного псевдонима к typesetприблизительно в 1990 г., а pdksh и его производным – в 1994 г.posh(на основеpdksh)удаленоtypeset(для строгого соответствия Политике Debian, которая требует local, но неtypeset).

Первоначально POSIX возражал против определения typesetна том основании, что это была динамическая область видимости.Итак, ksh93 (, переписанный в 1993 году Дэвидом Корном )ksh, переключился на статическую область видимости. Кроме того, в ksh93, в отличие от ksh88, локальная область видимости выполняется только для функций, объявленных с синтаксисом ksh(function f {...}), а не синтаксисом Борна (f() {...}), а псевдоним localбыл удален.

Однако бета-версия ksh93v -и окончательная версия от AT&T могут быть скомпилированы с экспериментальным режимом «bash» (, фактически включенным по умолчанию ), который выполняет динамическую область видимости (в любых формах функций, в том числе с localи typeset), когда ksh93вызывается как bash. localотличается от typesetв этом случае тем, что его можно вызвать только из функции. Этот режим bashбудет отключен по умолчанию в ksh2020 , хотя псевдонимы local/ declareдля typesetбудут сохранены, даже если режим bash не скомпилирован в(хотя все еще со статической областью видимости ).

yash(написан намного позже ), имеетtypeset(а-ля ksh88 ), но имеет псевдоним localтолько с версии 2.48 (декабря 2018 ).

@Schily поддерживает потомок оболочки Bourne, который недавно стал в основном совместимым с POSIX, называемый bosh, который поддерживает локальную область видимости с версии 2016 -07 -06 (с local, аналогично кash).

Таким образом,:

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

  • ksh, все реализации и их производные (ksh88, ksh93, pdksh и производные, такие как posh, mksh, OpenBSD sh ).
  • ash и все его производные (NetBSD sh, FreeBSD sh, dash, busybox sh)
  • баш
  • зш
  • яш
  • чушь

Что касается shразличных систем, обратите внимание, что есть системы, в которых POSIX shнаходится в/bin(больше всего ),и другие, где это не так (, как Solaris, где это/usr/xpg4/bin). Для реализации shна различных системах имеем:

  • ksh88 :большинство производных от SysV -коммерческих Unices (AIX, HP/UX, Solaris¹...)
  • bash :большинство систем GNU/Linux, Cygwin, macOS
  • ash :по умолчанию в Debian и большинстве производных (, включая Ubuntu, Linux/Mint ), хотя администратор может изменить его на bash или mksh. NetBSD, FreeBSD и некоторые их производные (, а не macOS ).
  • busybox sh :многие, если не большинство встроенных систем Linux
  • pdksh или производные :OpenBSD, MirOS

Теперь, чем они отличаются:

  • typeset(ksh, pdksh, bash, zsh, yash )vslocal(ksh88, pdksh, bash, zsh, ash, yash 2.48+ ).
  • статическая (ksh93, в function f {...}функция ), по сравнению с динамической областью видимости (во всех остальных оболочках ). Например, function f { typeset v=1; g; echo "$v"; }; function g { v=2; }; fвыводит 1или 2. См. также, как атрибут exportвлияет на область видимости в ksh93.
  • делает ли local/ typesetпросто переменную локальной (ash,bosh)или создает новый экземпляр переменной (другие оболочки ). Например, если v=1; f() { local v; echo "${v:-empty}"; }; fвыводит 1или empty(, см. также параметр localvar_inheritв bash 5.0 и выше ).
  • с теми, которые создают новую переменную, наследует ли новая атрибуты (, такие какexport)и/или тип, и какие из переменных в родительской области. Например, печатает ли export V=1; f() { local V=2; printenv V; }; f1, 2или ничего.
  • имеет ли эта новая переменная начальное значение (пустой, 0, пустой список, в зависимости от типа,zsh)или она изначально не установлена.
  • следует ли unset Vдля переменной в локальной области видимости оставить переменную unsetили просто очистить один уровень области видимости (mksh, yash, bashпри некоторых обстоятельствах ).Например, независимо от того, выводит ли v=1; f() { local v=2; unset v; echo "$v"; }1или ничего (, см. также параметр localvar_unsetв bash 5.0 и выше )
  • .
  • как и для export, является ли это ключевым словом или просто встроенной функцией или и тем, и другим, и при каких условиях оно считается ключевым словом.
  • аналогично export, анализируются ли аргументы как обычные аргументы команды или как присваивания (и при каком условии ).
  • можно ли объявить локальной переменной, которая была доступна только для чтения в родительской области.
  • взаимодействия с v=value myfunction, где myfunctionсам объявляет vлокальным или нет.

Это те, о которых я сейчас думаю. Проверьте ошибку группы austin выше для получения более подробной информации.

Что касается локальной области видимости для опций(оболочки, в отличие от переменных ), оболочки, поддерживающие ее:

  • ksh88(с синтаксисом определения функции ):, выполненным по умолчанию, я не знаю, как его отключить.
  • ash(с 1989 г. ):с local -. Это делает параметр $-(, в котором хранится список опций ), локальным.
  • ksh93:теперь выполняется только для функций function f {...}.
  • zsh(с 1995 года ). С setopt localoptions. Также с emulate -Lдля режима эмуляции (и его набора опций ), которые должны быть сделаны локальными для функции.
  • bash(с 2016 года )с local -, как в ash, но только для опций, управляемых set, а не тех, которыми управляет shopt.

¹ POSIX shв Solaris — это /usr/xpg4/bin/sh(, хотя в нем много ошибок совместимости, включая локальные опции для функций ). /bin/shдо Solaris 10 была оболочка Bourne (, поэтому не было локальной области видимости ), а поскольку Solaris 11 — это ksh93

1
05.02.2021, 21:06
2 ответа

Вам нужно использовать awk getlineдля чтения вывода в переменную. Вам также необходимо правильно установить локаль, чтобы перекодирование работало должным образом. Попробуйте это:

$ LC_ALL=C gawk '/DESCRIPTION/{
        "echo \""$0"\" | recode..html" | getline ff; print ff
       }' file 
    <DESCRIPTION><p>foo</p><p> </p><p> </p></DESCRIPTION>
2
18.03.2021, 22:32

Предполагая, что документ правильно сформирован, с некоторым корневым узлом root...

$ cat file.xml
<root>
    <ITEM_ID>foo</ITEM_ID>
    <PRODUCTNAME>bar</PRODUCTNAME>
    <DESCRIPTION><p>foo</p><p> </p><p> </p></DESCRIPTION>
    <URL>bar</URL>
    <IMGURL>foo</IMGURL>
    <IMGURL_ALTERNATIVE></IMGURL_ALTERNATIVE>
</root>

Затем,

$ xmlstarlet ed -u '/root/DESCRIPTION' -v "$( xmlstarlet sel -t -c '/root/DESCRIPTION/*' file.xml )" file.xml
<?xml version="1.0"?>
<root>
  <ITEM_ID>foo</ITEM_ID>
  <PRODUCTNAME>bar</PRODUCTNAME>
  <DESCRIPTION>&lt;p&gt;foo&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt; &lt;/p&gt;</DESCRIPTION>
  <URL>bar</URL>
  <IMGURL>foo</IMGURL>
  <IMGURL_ALTERNATIVE/>
</root>

Здесь происходит то, что xmlstarlet selиспользуется для извлечения копии узлов под узлом /root/DESCRIPTION. Вот что делает xmlstarlet sel -t -c '/root/DESCRIPTION/*' file.xmlи возвращает строку <p>foo</p><p> </p><p> </p>.

Затем эта строка используется в качестве нового текстового значения для узла /root/DESCRIPTIONс помощью команды xmlstarlet ed. Новое значение получается из подстановки команды.

Обратите внимание, что значение автоматически кодируется XML.

2
18.03.2021, 22:32

Теги

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