САС сохранить шаблон в \ 1 для следующего блока / команды - PullRequest
3 голосов
/ 20 января 2020

Я хочу сопоставить шаблон, но замените что-то другое на соответствующий шаблон.

pattern1    X1 X2 X3
pattern2    X4 X5
...

должно быть преобразовано в

pattern1-1
pattern1-2
pattern1-3

pattern2-4
pattern2-5
...

Я не могу просто заменить 'X', потому что это несколько раз подряд.

Я пытался sed -r '/(pattern[0-9])/ { s/X/\n\1/g; }', но это даст мне ошибку invalid reference \1 on `s.

Есть ли другой способ сделать это?

Ответы [ 3 ]

0 голосов
/ 20 января 2020

Это может работать для вас (GNU sed):

sed -E 's/(\S+)\s+X(\S+)/\1-\2\n\1/;/-/!s/.*//;P;D' file

Использовать сопоставление с шаблоном, чтобы сопоставить первое поле и другое, начинающееся с X. Манипулируйте желаемым результатом, а затем снова добавьте новую строку и первое поле. Печать / удаление до и включая первую новую строку, и, если строка не соответствует удалению, ее содержимое, т. Е. Печать пустой строки.

Если пустая строка не требуется, используйте:

sed -E 's/(\S+)\s+X(\S+)/\1-\2\n\1/;/-/P;D' file
0 голосов
/ 20 января 2020

L oop вручную, пока не будет найдено соответствие шаблону.

sed '
    : loop
    # match the first line
    # ex. replace:
    #   pattern1 X1 X2 X3
    # for two lines:
    #   pattern1 X1 X2
    #   pattern1-3
    s/\(pattern[0-9]\)\( *[^\n]*\)X\([0-9]\)/\1\2\n\1-\3/
    # if the last s command was successfull, branch to loop
    t loop
    # remove first line
    # the "pattern1" will be left
    s/[^\n]*\n//
'

Следующий скрипт:

cat <<EOF |
pattern1    X1 X2 X3
pattern2    X4 X5
EOF
sed ':a;s/\(pattern[0-9]\)\( *[^\n]*\)X\([0-9]\)/\1\2\n\1-\3/;ta;s/[^\n]*\n//'

на выходах repl :

pattern1-1
pattern1-2
pattern1-3
pattern2-4
pattern2-5

Если вам нужен перевод строки между pattern1 и pattern2, вы можете добавить s/$/\n/ в конец скрипта.

0 голосов
/ 20 января 2020

Не могли бы вы попробовать следующее. Должно быть легко в awk ИМХО.

awk 'BEGIN{OFS="-"}{for(i=2;i<=NF;i++){sub(/[^0-9]+/,"",$i);print $1,$i}}' Input_file

Объяснение: Добавление подробного объяснения для приведенного выше кода.

awk '                        ##Starting awk code from here.
BEGIN{                       ##Starting BEGIN block for this code from here.
  OFS="-"                    ##Setting OFS as - here.
}
{
  for(i=2;i<=NF;i++){        ##Starting for loop from i=2 to till value of NF here.
    sub(/[^0-9]+/,"",$i)     ##Substituting everything apart from digits in current field with NULL.
    print $1,$i              ##Printing first field and edited value of current field.
  }
}
' Input_file                 ##Mentioning Input_file name here.
...