Как использовать «sed», чтобы добавить динамический префикс для каждого числа в списке целых чисел? - PullRequest
0 голосов
/ 21 апреля 2019

Как я могу использовать sed для добавления динамического префикса к каждому числу в целочисленном списке?

Например:

У меня есть строка "A-1,2,3,4,5", я хочу преобразовать ее в строку "A-1,A-2,A-3,A-4,A-5" - что означает, что я хочу добавить префикс первого целого числа, т.е. "A-" к каждому номеру списка.

Если у меня есть строка типа "B-1,20,300", я хочу преобразовать ее в строку "B-1,B-20,B-300".

Я не могу использовать группы захвата RegEx, поскольку для глобального сопоставления они не сохраняют свое значение в последующих сопоставлениях.

Ответы [ 6 ]

2 голосов
/ 21 апреля 2019

Когда дело доходит до циклических конструкций в sed, я люблю использовать переводы строк в качестве маркеров для мест, которые мне еще предстоит обработать.Это делает сопоставление намного проще, и я знаю, что они не во вводе, потому что мой ввод - это текстовая строка.

Например:

$ echo A-1,2,3,4,5 | sed 's/,/\n/g;:a s/^\([^0-9]*\)\([^\n]*\)\n/\1\2,\1/; ta'
A-1,A-2,A-3,A-4,A-5

Это работает следующим образом:

s/,/\n/g                                # replace all commas with newlines (insert markers)
:a                                      # label for looping
  s/^\([^0-9]*\)\([^\n]*\)\n/\1\2,\1/   # replace the next marker with a comma followed
                                        # by the prefix
ta                                      # loop unless there's nothing more to do.

Подход похож на @ potong's, но я нахожу регулярное выражение гораздо более читабельным - \([^0-9]*\) захватывает префикс, \([^\n]*\) захватывает все до следующего маркера (то есть все, что уже было обработано),и тогда нужно просто собрать его в замене.

2 голосов
/ 21 апреля 2019

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

sed -E ':a;s/^((([^-]+-)[^,]+,)+)([0-9])/\1\3\4/;ta' file

Использует сопоставление с шаблоном и цикл для замены числа после запятой на префикс первого столбца и это число.

1 голос
/ 21 апреля 2019

Не используйте sed, просто используйте другой стандартный инструмент для работы с текстом UNIX, awk:

$ echo 'A-1,2,3,4,5' | awk '{p=substr($0,1,2); gsub(/,/,"&"p)}1'
A-1,A-2,A-3,A-4,A-5

$ echo 'B-1,20,300' | awk '{p=substr($0,1,2); gsub(/,/,"&"p)}1'
B-1,B-20,B-300
0 голосов
/ 21 апреля 2019

если ваши данные в файле 'd', попробуйте на gnu sed:

sed -E 'h;s/^(\w-).+/\1/;x;G;:s s/,([0-9]+)(.*\n(.+))/,\3\1\2/;ts; s/\n.+//' d
0 голосов
/ 21 апреля 2019

Не могли бы вы попробовать следующее (если все в порядке с awk).

awk '
BEGIN{
  FS=OFS=","
}
{
  for(i=1;i<=NF;i++){
    if($i !~ /^A/&&$i !~ /\"A/){
        $i="A-"$i
    }
  }
}
1' Input_file
0 голосов
/ 21 апреля 2019

Предполагая, что это для сценариев оболочки, вы можете сделать это с 2 seds:

set string = "A1,2,3,4,5"
set prefix = `echo $string | sed 's/^\([A-Z]\).*/\1/'`
echo $string | sed 's/,\([0-9]\)/,'$prefix'-\1/g'

Выход

A1,A-2,A-3,A-4,A-5

С

set string = "B-1,20,300"

Вывод

B-1,B-20,B-300
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...