Вы можете использовать поиск, чтобы указать строку для сопоставления, а затем использовать более простое регулярное выражение в замене:
sed "/file1\.jar (MD5: [0-9A-Fa-f]*)/s/(MD5: [^)]*)/(MD5: $(md5 file1.jar | awk '{print $4}'))/"
, которое использует нотацию $(...)
для запуска команды.Хитрый бит в этом находится в конце, где появляется последовательность ))/"
.Первая закрывающая скобка - это конец обозначения $(...)
;второй символ в тексте замены.
Первое регулярное выражение /file1\.jar (MD5: [0-9A-Fa-f]*)/
довольно точно указывает строку, которую нужно сопоставить.Затем, зная, что это правильная строка, шаблон в замене может быть проще: поисковая часть /(MD5: [^)]*)/
ищет только данные MD5 в скобках, будучи уверенными в том, что, хотя многие другие строки содержат тот же шаблон, подстановка будетприменяется только к одной желаемой строке.
Я мог бы склоняться к использованию:
md5=$(md5 file1.jar | awk '{print $4}')
sed "/file1\.jar (MD5: [0-9A-Fa-f]*)/ s/(MD5: [^)]*)/(MD5: $md5)/"
, которая проясняет, что к чему, значительно (и не включает в себя горизонтальную полосу прокрутки на SO).Вы можете быть еще более точным в шаблоне сопоставления строк:
md5=$(md5 file1.jar | awk '{print $4}')
sed "/^file1\.jar (MD5: [0-9A-Fa-f]\{32\})\$/ s/(MD5: [^)]*)/(MD5: $md5)/"
Это требует ровно 32 шестнадцатеричных цифр и закрывающих скобок в конце строки.
Один изв комментариях спрашивается:
Может ли sed работать таким образом, чтобы замещающая строка заменяла только совпадающие группы в шаблоне поиска?Например, учитывая 's/A B \(D\)/C/'
, он выводит A B C
.
Если я понимаю (разъяснение) вопроса, то вы можете делать то, что хотите, с соответствующим захватом - но запасная часть будетнеобходимо указать именно то, что вы хотите в качестве вывода (никаких ярлыков, как вы, кажется, после).Так, например, вы могли бы написать что-то вроде:
s/\(A B \)\(D\)/\1C/
(где для захвата \(D\)
не требуется захватывать скобки, так как захваченный материал не используется при замене, и вы можете написать либоиз:
s/\(A B \)D/\1C/
s/\(A B\) D/\1 C/
Вы также можете сделать:
/A B / s/D/C/
. Здесь есть поиск (для последовательности A B
), а затем заменитель ищет D
и заменяет его наC
. Это в основном то, что предлагает основной ответ. Возможно, вы также можете сделать:
/\(A B\) D/ s//\1 C/
«Пустой поиск» должен повторить совпадение, но замена должна быть записана полностью,и это фактически то же самое, что и одна из предыдущих команд:
s/\(A B\) D/\1 C/