
Может ли кто-нибудь объяснить мне этот код sed ниже?
sed -n '
/Policy Name:/! d
s/.*:\s\+//
h
:1
n
/Active:\s*no/d
/HW\//!b1
:2
s/.*\s\(\S*\)\s*/\1/
G
s/\n/\t/p
n
/^\s*$\|Include:/! b2
'
Я хочу отредактировать, чтобы добавить информацию «Тип политики:». Когда я заменяю ее на «Имя политики:», все работает нормально. Однако, когда я добавляю раздел, как показано ниже, это, очевидно, не работает, потому что я пытаюсь сделать это, не понимая.
sed -n '
/Policy Name:/! d
s/.*:\s\+//
h
:1
n
/Policy Type:/! d
s/.*:\s\+//
h
:1
n
/Active:\s*no/d
/HW\//!b1
:2
s/.*\s\(\S*\)\s*/\1/
G
s/\n/\t/p
n
/^\s*$\|Include:/! b2
'
Также у меня есть решение для эквивалентного кода AIX ниже с того же форума, мне нужно его понять, чтобы отредактировать его и добавить тип политики.
# define constants
SPC=`echo x | tr x '\040'`
TAB=`echo x | tr x '\011'`
NL=
# custom regex for...
s="[$SPC$TAB]"; # horizontal whitespace
S="[^$SPC$TAB]"; # non-whitespace
# POSIX compliant sed code...
sed -ne "
/Policy Name:/!d
s/.*:$s\{1,\}//
h
:1
n
/Active:$s*no/d
/HW\//!b1
:2
s/.*$s\($S*\)$s*/\1/
G
s/\n/$TAB/p
n
/^$s*\$/d
/Include:/d
b2
" yourfile
Входной файл
Policy Name: Today
Policy Type: Standard
Active: yes
Effective date: 01/24/2014 11:17:05
Client Encrypt: no
LC/CY/Custmr: EU NY Cindy
BU CA Victor
GU MI Bob
Include:
Policy Name: Tomorrow
Policy Type: Oracle
Active: yes
Effective date: 01/26/2014 11:17:05
Client Encrypt: no
LC/CY/Custmr: MU LA Martha
EU CA Sam
Include:
Policy Name: Yesterday
Policy Type: Oracle
Active: no
Effective date: 01/21/2014 11:17:05
Client Encrypt: no
LC/CY/Custmr: NV IL Joe
Include:`
Желаемый результат
Cindy Today Standard
Victor Today Standard
Bob Today Standard
Martha Tomorrow Oracle
Sam Tomorrow Oracle
решение1
Хорошо, давайте сделаем это шаг за шагом:
sed -n '
Опция не -n
выводит sed
ничего, если не указано иное.
/Policy Name:/! d
Все строки, которые не содержат, Policy name:
удаляются. Остальная часть скрипта обрабатывается только в следующих циклах.
s/.*:\s\+//
h
Это удалит все до пробелов :
и конечных символов, а остальное поместит в буфер хранения для последующего использования.
:1
n
Это начало цикла чтения новых строк.
/Active:\s*no/d
Строки с таким шаблоном удаляются, поэтому, очевидно, нет интереса к неактивным.
/HW\//!b1
И теперь мы переходим к циклу, :1
если строка не содержитHW/
:2
s/.*\s\(\S*\)\s*/\1/
В начале следующего цикла удалите все, кроме последней последовательности непустых символов.
G
s/\n/\t/p
Затем добавьте имя политики, хранящееся в буфере удержания, разделенное табуляцией, и выведите эту строку на печать.
n
/^\s*$\|Include:/! b2
'
и это повторяется со следующими строками, пока мы не достигнем заданного шаблона.
Следует отметить, что это крайне непереносимый код, который не будет работать во многих sed
версиях.
Редактировать:Чтобы добавить тип политики в качестве третьего столбца, необходимо добавить эту строку в скрипт до или после проверки Active:
:
/Policy Type:/{s/.*:\s*//;H;}
То есть: если строка содержит указанную строку, выполнить команды между {}
. Эти команды удаляют часть до :
и конечных пробелов и добавляют остальную часть строки (которая должна содержать тип политики) в буфер удержания. Таким образом, буфер удержания содержит имя и тип политики, разделенные новой строкой. Поэтому, когда мы добавляем это с G
, будет две новые строки для замены, поэтому команда замены должна получить флаг g
для замены всех вхождений:
s/\n/\t/gp
Скрипт AIX в основном тот же, но избегает расширений GNU для регулярных выражений. В основном используются переменные для соответствия пробелам или табуляциям, так как \t
не будут работать во всех sed
вариантах, а также +
для "один или несколько" необходимо заменить на\{1,\}