Замена частей строки

#python #string #bash #sed #split

#python #строка #bash #sed #разделение

Вопрос:

На самом деле мой вопрос довольно прост: у меня есть строка типа: 101222_1_1_ab ; Я надеюсь изменить ее на: 101222_1_ab_1

Какие команды bash я должен использовать? и что делать в python? Спасибо

Ответ №1:

Самый простой механизм, который я могу придумать, это использовать awk(1) :

 $ echo 101222_1_1_ab | awk -F_ '{print $1 "_" $2 "_" $4 "_" $3;}'
101222_1_ab_1
  

-F_ Просит awk(1) разделить поля на символы подчеркивания.

Обновление Гленн Джекман рекомендует следующую, гораздо более разборчивую версию:

 awk -F_ -v OFS=_ '{print $1, $2, $4, $3}'
  

Комментарии:

1. Вместо жесткого кодирования символов подчеркивания внутри тела awk вы могли бы использовать: awk -F_ -v OFS=_ '{print $1, $2, $4, $3}'

2. @glenn, да, это намного лучше. Спасибо!

Ответ №2:

 echo 101222_1_1_ab | sed -r -e 's/(.*_.*_)(.*)_(.*)/13_2/'
  

Ответ №3:

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

 # echo "101222_1_1_ab" | sed -re 's/(_[^_] )(_.*)$/21/'
101222_1_ab_1
  

Ответ №4:

FWIW, я бы использовал awk для этого.

 $ echo 101222_1_1_ab | awk 'BEGIN {FS = OFS = "_"} {print $1, $2, $4, $3}' 
101222_1_ab_1
  

Но поскольку вы спрашиваете:

и что делать в python?

 >>> s = '101222_1_1_ab'
>>> s.split('_')
['101222', '1', '1', 'ab']
>>> l = s.split('_')
>>> l[0], l[1], l[3], l[2]
('101222', '1', 'ab', '1')
>>> '_'.join((l[0], l[1], l[3], l[2]))
'101222_1_ab_1'
  

Ответ №5:

Если вы хотите использовать sed, это разделит символы подчеркивания и изменит порядок:

 echo 101222_1_1_ab | sed 's/(.*_.*)_(.*)_(.*)/1_3_2/'
  

Редактировать Как указывает @dmitry.malikov, -r опция может сделать ее намного более читаемой:

 echo 101222_1_1_ab | sed -r 's/(.*_.*)_(.*)_(.*)/1_3_2/'
  

Комментарии:

1. Это выглядит лучше без такого большого количества экранирований echo 101222_1_1_ab | sed -r -e 's/(.*_.*_)(.*)_(.*)/13_2/'

2. Кстати, ваш пример возвращает 101222_1_1_ab

3. @dmitry.malikov: В предыдущей правке я вырезал и вставил в нее лишние одинарные кавычки, что сделало ее неверной. Я это исправил.

Ответ №6:

Просто с помощью bash:

 word=101222_1_1_ab
new=$(
  IFS=_
  parts=($word)
  tmp=${parts[2]}; parts[2]=${parts[3]}; parts[3]=$tmp
  printf "%s" "${parts[*]}"
)
echo $new # => 101222_1_ab_1
  

Комментарии:

1.Это можно было бы сократить до #!/bin/bash word='101222_1_1_ab' IFS='_' parts=( $word ) echo "${parts[0]}_${parts[1]}_${parts[3]}_${parts[2]}"

Ответ №7:

Bash:

 #!/bin/bash
word='101222_1_1_ab' IFS='_' parts=( $word )
echo "${parts[0]}_${parts[1]}_${parts[3]}_${parts[2]}"
  

(хотел добавить это в ответ Гленну Джекману)