Как заменить конкретное поле в файле на основе содержания другого поля?

У меня есть файл со следующим форматом:

A 485C72F95C72E15C EXTERNAL
B CC32480A3247F84A SYSTEM
C EC2A63F12A63B76C EXTERNAL

Я хочу предоставить букву в первом столбце с помощью значения переменной 'буквы' и заменить значение во втором столбце со значением, которое я предоставляю в переменном 'идентификаторе'. Третий столбец может или не может отличаться или соответствовать в любом случае. Первые и вторые столбцы никогда не будут содержать пробелы или специальные символы.

Я попытался использовать sed, но мой sed-fu не силен. Я придумал это:

letter=A
id=MYNEWIDSTRING
sed "/$letter /s/[^ ]*/$id/2"

Вывод:

A MYNEWIDSTRING EXTERNAL
B MYNEWIDSTRING SYSTEM
C EC2A63F12A63B76C EXTERNAL

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

Я знаю для использования sed -i отредактировать оперативный файл, но не выполнение его все же, поскольку моя команда все еще немного изворотлива.

Где я пошел не так, как надо, или я должен использовать другой метод?

4
задан 3 November 2016 в 21:42

2 ответа

Привяжите его (^, запуск строки) так, чтобы эти A был только подобран, если это - первый символ:

$ letter=A; id=MYNEWIDSTRING; sed "/^$letter /s/[^ ]*/$id/2" file
A MYNEWIDSTRING EXTERNAL
B CC32480A3247F84A SYSTEM
C EC2A63F12A63B76C EXTERNAL

между прочим, если Вы хотите передать переменные sed, но Вам нужно сильное заключение в кавычки, помнят, что можно включить и выключить заключение в кавычки при добавлении двойных кавычек для переменных - ужасный, но вероятно лучшая практика в целом:

sed '/^'"$letter"' /s/[^ ]*/'"$id"'/2'
5
ответ дан 1 December 2019 в 08:59

Каждый раз, когда Вы имеете дело со структурированными данными, я достиг бы awk или perl вместо sed.

Например,

awk -v letter="A" -v id="MYNEWIDSTRING" '$1 == letter {$2=id}1' file
A MYNEWIDSTRING EXTERNAL
B CC32480A3247F84A SYSTEM
C EC2A63F12A63B76C EXTERNAL

или

perl -alne '
  BEGIN{$letter = shift; $id = shift;} 
  print join " ", $F[0], $F[0] eq $letter ? $id : $F[1], @F[2..$#F]
' 'A' 'MYNEWIDSTRING' file

Более новые версии GNU awk имеют a -i (--in-place) флаг; в других необходимо было бы использовать явный временный файл; жемчуг должен иметь a -i в любом случае.

5
ответ дан 1 December 2019 в 08:59

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

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