Как я заменяю весь occourences символа кроме последнего с помощью sed?

Например, я получил строку как это:

44567743346_567864_56788_5677_3

Я хочу измениться весь _ в :, за исключением последнего изменился бы в \. Ожидаемый вывод:

44567743346:567864:56788:5677\3
2
задан 15 August 2015 в 17:27

4 ответа

$ echo '44567743346_567864_56788_5677_3' | sed -r 's|_|:|g; s|:([^:]*)$|\\\1|'
44567743346:567864:56788:5677\3

Это использует две sed команды замены. Первое, s|_|:|g изменения все подчеркивания к двоеточиям. Второе, s|:([^:]*)$|\\\1| находит последнее двоеточие и изменяет его на обратную косую черту.

Изменение каждой четвертой строки файла этот путь

sed -r '1~4{s|_|:|g; s|:([^:]*)$|\\\1|;}' file

Для изменения оперативного файла:

sed -i -r '1~4{s|_|:|g; s|:([^:]*)$|\\\1|;}' file
4
ответ дан 2 December 2019 в 01:45

Если Вы знаете количество последнего вхождения _ например, в Вашем примере последнее _ является 4-м _ в строке можно сделать:

sed 's/_/\\/4; s/_/:/g' file.txt

Здесь мы сначала преобразовали 4-е (последнее) возникновение _ кому: \, затем остающиеся случаи _ преобразовываются в :.

Например:

$ echo '44567743346_567864_56788_5677_3' | sed 's/_/\\/4; s/_/:/g'
44567743346:567864:56788:5677\3

С другой стороны, если Вы не знаете положения последнего вхождения _, можно жадно соответствовать до последнего вхождения _, замените его \ и затем замените остальных : :

sed -r 's/^(.*)_/\1\\/; s/_/:/g' file.txt

Например:

$ echo '44567743346_567864_56788_5677_3' | sed -r 's/^(.*)_/\1\\/; s/_/:/g'
44567743346:567864:56788:5677\3
0
ответ дан 2 December 2019 в 01:45

Почему sed если это - более простое использование awk?

awk -F_ '{printf "%s",$1; for(i=2;i<NF;i++){printf ":%s",$i}; printf "\\%s\n",$NF}' your_input_file

И поскольку Вы сказали в комментарии? Вам нужна только каждая четвертая строка

awk -F_ '(NR % 4) == 1 {printf "%s",$1; for(i=2;i<NF;i++){printf ":%s",$i}; printf "\\%s\n",$NF; next} {print}'  your_input_file

Пример

Входной файл

% cat foo
1_44567743346_567864_56788_5677_3
2_908798_08098_878_24332_24_24244_22
3_44567743346_567864_56788_5677_3
4_908798_08098_878_24332_24_24244_22
1_44567743346_567864_56788_5677_3
2_908798_08098_878_24332_24_24244_22
3_44567743346_567864_56788_5677_3
4_908798_08098_878_24332_24_24244_22
1_44567743346_567864_56788_5677_3
2_908798_08098_878_24332_24_24244_22
3_44567743346_567864_56788_5677_3
4_908798_08098_878_24332_24_24244_22
1_44567743346_567864_56788_5677_3
2_908798_08098_878_24332_24_24244_22
3_44567743346_567864_56788_5677_3
4_908798_08098_878_24332_24_24244_22

Вывод команды для изменения каждой четвертой строки

% awk -F_ '(NR % 4) == 1 {printf "%s",$1; for(i=2;i<NF;i++){printf ":%s",$i}; printf "\\%s\n",$NF; next} {print}' foo
1:44567743346:567864:56788:5677\3
2_908798_08098_878_24332_24_24244_22
3_44567743346_567864_56788_5677_3
4_908798_08098_878_24332_24_24244_22
1:44567743346:567864:56788:5677\3
2_908798_08098_878_24332_24_24244_22
3_44567743346_567864_56788_5677_3
4_908798_08098_878_24332_24_24244_22
1:44567743346:567864:56788:5677\3
2_908798_08098_878_24332_24_24244_22
3_44567743346_567864_56788_5677_3
4_908798_08098_878_24332_24_24244_22
1:44567743346:567864:56788:5677\3
2_908798_08098_878_24332_24_24244_22
3_44567743346_567864_56788_5677_3
4_908798_08098_878_24332_24_24244_22

Вывод команды для изменения каждой строки

% awk -F_ '{printf "%s",$1; for(i=2;i<NF;i++){printf ":%s",$i}; printf "\\%s\n",$NF}' foo                               
1:44567743346:567864:56788:5677\3
2:908798:08098:878:24332:24:24244\22
3:44567743346:567864:56788:5677\3
4:908798:08098:878:24332:24:24244\22
1:44567743346:567864:56788:5677\3
2:908798:08098:878:24332:24:24244\22
3:44567743346:567864:56788:5677\3
4:908798:08098:878:24332:24:24244\22
1:44567743346:567864:56788:5677\3
2:908798:08098:878:24332:24:24244\22
3:44567743346:567864:56788:5677\3
4:908798:08098:878:24332:24:24244\22
1:44567743346:567864:56788:5677\3
2:908798:08098:878:24332:24:24244\22
3:44567743346:567864:56788:5677\3
4:908798:08098:878:24332:24:24244\22
0
ответ дан 2 December 2019 в 01:45

Простой Используя sed

echo "44567743346_567864_56788_5677_3" | rev | sed "s/_/:/2g" | sed 's/_/\\/' | rev


Теперь давайте посмотрим, как это работает:-

1) rev инвертирует строку,

это становится 3_7765_88765_468765_64334776544

2) sed "s/_/:/2g замены все возникновение _ кому: : кроме первого вхождения в обратной строке,

это становится, 3_7765:88765:468765:64334776544

3) Затем sed т.е. sed 's/_/\\/' замены просто первое вхождение _ кому: \.

Это становится, 3\7765:88765:468765:64334776544

4) rev реверсы эта обработанная строка

Теперь, заключительная строка является:-

44567743346:567864:56788:5677\3

Теперь, его сделанный!

Примечание: Это не дает много эффективности. Здесь просто, потому что его простое

2
ответ дан 2 December 2019 в 01:45

Другие вопросы по тегам:

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