Как я могу заменить несколько экземпляров символа одинаковым количеством экземпляров другого символа в linux sed?
Мне нужно заменить повторяющийся набор символов (2 или более) на точное количество заменяющих символов. Мне нужно сделать это либо с помощью sed, либо внутри vi.
Примеры
"abc,,,def" becomes "abc|||dev"
"1245d,,,,,22" becomes "1245d|||||22"
Спасибо
3 ответа
Извините, что не комментирую, у меня нет 50 репутации.
Это решение не удастся, если есть больше шаблонов, таких как abc,,,def,g
,
sed -n 's/[^,],,/&/;tsubs;p;d;:subs s/,/|/g;p' <<<'abc,,,def
abc,,def
abc,,,def,g
abc,def'
Труба через sed
, лайк
echo "abc,,,def" | sed 's/,/|/g'
но я бы порекомендовал использовать
tr ',' '|'
в этом случае.
Это практически невозможно из-за работы регулярных выражений. Как уже указывал jvb, решение является простым (хотя и не обязательно коротким), если известно максимальное количество последовательных исходных символов. Если нет, то можно сначала изменить все исходные символы, а затем снова изменить отдельные символы на втором шаге. Однако это работает только в том случае, если целевой символ не встречается во входном потоке или если вы можете использовать символ, о котором известно, что он не встречается во входном потоке, в качестве промежуточной цели.
Кроме того, вам необходимо принять во внимание угловые случаи одного исходного символа, встречающегося в начале или конце строки. Таким образом:
tr ',' '|' < file | sed 's/\([^|]\)|\([^|]\)/\1,\2/;s/^|\([^|]\)/,\1/;s/\([^|]\)|$/\1,/'
или же
sed 's/,/|/g;s/\([^|]\)|\([^|]\)/\1,\2/;s/^|\([^|]\)/,\1/;s/\([^|]\)|$/\1,/' file
Решение с использованием языка, который имеет понятие длины строки, будет более надежным.