Использование команды sed в сценарии оболочки для подстроки и замены нужной позиции

Я работаю с данными в текстовом файле и не могу найти способ с помощью sed выбрать подстроку в фиксированной позиции и заменить ее.

Вот что у меня есть:

X|001200000000000000000098765432|1234567890|TQ

Это то, что мне нужно:

‘X’,’00000098765432’,’1234567890’,’TQ’

Следующий код в sed дает нужную мне подстроку (00000098765432), но не перезаписывает нужную позицию

echo “ X|001200000000000000000098765432|1234567890|TQ” | sed “s/
*//g;s/|/‘,’/g;s/^/‘/;s/$/‘/“

Не могли бы вы помочь мне?

Похоже, вы пытаетесь удалить первые 4 символа. Это правильно?

netskink 09.05.2022 16:00

При извлечении данных с помощью конвейера я хочу удалить 16 символов перед второй позицией. образец: от 001200000000000000000098765432 до 00000098765432

Aungkan Cheangka 09.05.2022 16:08

В вашем коде и примере используются «умные кавычки», пожалуйста, редактировать те, кто вместо этого использует простые кавычки ASCII, ' и ".

Ed Morton 10.05.2022 03:00
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
72
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Вместо sed я бы использовал awk для этого.

echo "X|001200000000000000000098765432|1234567890|TQ" | awk 'BEGIN {FS = "|";OFS = ","} {print $1,substr($2,17,14),$3,$4}'

Дает вывод:

X,00000098765432,1234567890,TQ

Вот как это работает:

FS = Разделитель полей (во вводе)

OFS = разделитель полей вывода (так, как вы хотите, чтобы вывод был разделен)

BEGIN -> думайте об этом как о месте, где устанавливаются конфигурации. Он запускается только один раз. Итак, вы говорите, что хотите, чтобы вывод был разделен запятой, а ввод - с разделителем канала.

substr($2,17,14) -> Возьмите $2 (т.е. второе поле — awk начинает отсчет с 1 — и затем примените к нему подстроку. 17 означает начальную позицию символа, а 14 означает количество символов с этой позиции и далее)

На мой взгляд, это намного удобнее для чтения и обслуживания, чем версия sed, которая у вас есть.

substr($2,17,14) может быть просто substr($2,17), вам не нужно указывать количество символов, если вы просто хотите перейти в конец строки.
Ed Morton 10.05.2022 03:08
Ответ принят как подходящий

Если вы хотите поставить кавычки, я бы все равно использовал awk.

$: awk -F'|' 'BEGIN{q = "\047"} {print  q $1 q","q substr($2,17,14) q","q $3 q","q $4 q"\n"}' <<< "X|001200000000000000000098765432|1234567890|TQ"
'X','00000098765432','1234567890','TQ'

Если вы просто хотите использовать sed, обратите внимание, что вы сказать выше хотите удалить 16 символов, но на самом деле вы удаляете только 14.

$: sed -E "s/^(.)[|].{14}([^|]+)[|]([^|]+)[|]([^|]+)/'\1','\2','\3','\4'/" <<< "X|0012000000000000000098765432|1234567890|TQ"
'X','00000098765432','1234567890','TQ'

Использование sed

$ sed "s/|\(0[0-9]\{15\}\)\?/','/g;s/^\|$/'/g" input_file
'X','00000098765432','1234567890','TQ'
awk -v del1 = "\047" \
    -v del2 = "," \
    -v start = "3" \
    -v len = "17" \
    '{
         gsub(substr($0,start+1,len),"");
         gsub(/[\|]/,del1 del2 del1);
         print del1$0del1
    }' input_file

'X',00000098765432','1234567890','TQ'

@EdMorton: изменено на len

ufopilot 10.05.2022 07:43

Используя любой POSIX awk:

$ echo 'X|001200000000000000000098765432|1234567890|TQ' |
awk -F'|' -v OFS = "','" -v q = "'" '{sub(/.{16}/,"",$2); print q $0 q}'
'X','00000098765432','1234567890','TQ'

не так элегантно, как я надеялся, но он выполняет свою работу:

'X','00000098765432','1234567890','TQ'

    # gawk profile, created Mon May  9 21:19:17 2022
    # BEGIN rule(s)

    'BEGIN {
     1     _ = sprintf("%*s", (__ = +2)^++__+--__*++__,__--)
     1            gsub(".", "[0-9]", _)
     1             sub("$",     "$", _)
     1    FS = "[|]"
     1   OFS = "\47,\47"
    }

    # Rule(s)

     1     (NF *= NF == __*__) * sub(_,  "|&",   $__) * \
        sub("^.*[|]", "", $__) * sub(".+", "\47&\47")    }'

Протестировано и подтверждено, работает на gnu gawk 5.1.1, mawk 1.3.4, mawk 1.9.9.6 и macosx nawk

The 4Chan Teller

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