Например, я получил строку как это:
44567743346_567864_56788_5677_3
Я хочу измениться весь _
в :
, за исключением последнего изменился бы в \
. Ожидаемый вывод:
44567743346:567864:56788:5677\3
$ 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-м _
в строке можно сделать:
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
Почему 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
Простой Используя 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
Теперь, его сделанный!
Примечание: Это не дает много эффективности. Здесь просто, потому что его простое