The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]

форумы  помощь  поиск  регистрация  майллист  ВХОД  слежка  RSS
"Вопрос по использованию sed для редактирования файла"
Вариант для распечатки  
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [Проследить за развитием треда]

"Вопрос по использованию sed для редактирования файла"  
Сообщение от Roman K email on 30-Янв-07, 08:27 
Здравствуйте!

Есть некий файл вида:

file1:
=====================================
This is address 000075AF
String 1
String 2
This is address 0000753D
String 1
String 2
...
=====================================

Есть также другой файл, в котором адресам сопоставлены имена:

file2:
=====================================
Name1   000075AF
Name2   0000753D
...
=====================================

Требуется преобразовать первый файл file1, заменить там адреса на имена.
Должно получиться такое:
=====================================
Name1
String 1
String 2
Name2
String 1
String 2
=====================================

В общем-то, это не проблема. Но я сейчас пробую изучить возможности sed и вопрос возник такой: возможно-ли сделать это командой sed в одну строку? Вопрос чисто теоретический, призванный глубже понять возможности sed.

В общем-то, в редакторе sed есть команда s///, которая заменяет одно на другое. Во второй части команды можно поставить "\1", означающее найденную часть.
Поэтому, к примеру, выделение адреса тривиально:

sed "s/This is address \([0-9A-F]*\)/\1/" file1 > out

Пусть есть некий элементарный скрипт, выполняющий поиск во втором файле и возвращающий имя:

script:
=====================================
#!/bin/sh
grep $1 file2 | awk '{print $1}'
=====================================

Теперь попробуем подставить во вторую часть результат выполнения этого скрипта:
sed "s/This is address \([0-9A-F]*\)/`./script '\1'`/" file1 > out

Получаем ошибку: "grep: invalid back reference"

В то же время какое-нибудь элементарное эхо работает вполне прилично:
sed "s/This is address \([0-9A-F]*\)/`echo __'\1'__`/" file1 > out

Получается вот что:
=====================================
__000075AF__
String 1
String 2
__0000753D__
String 1
String 2
...
=====================================

В идеале должно получиться нечто такое:
sed "s/This is address \([0-9A-F]*\)/`grep '\1' file2 | awk '{print $1}'`/" file1 > out

Пожалуйста, проконсультируйте по вышеописанному. Почему grep не работает, а echo работает?
Спасибо!

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

 Оглавление

Сообщения по теме [Сортировка по времени, UBB]


1. "Вопрос по использованию sed для редактирования файла"  
Сообщение от perece on 06-Фев-07, 20:16 
>Здравствуйте!
>
>Есть некий файл вида:
>
>file1:
>=====================================
>This is address 000075AF
>String 1
>String 2
>This is address 0000753D
>String 1
>String 2
>...
>=====================================
>
>Есть также другой файл, в котором адресам сопоставлены имена:
>
>file2:
>=====================================
>Name1   000075AF
>Name2   0000753D
>...
>=====================================
>
>Требуется преобразовать первый файл file1, заменить там адреса на имена.
>Должно получиться такое:
>=====================================
>Name1
>String 1
>String 2
>Name2
>String 1
>String 2
>=====================================
>
>В общем-то, это не проблема. Но я сейчас пробую изучить возможности sed
>и вопрос возник такой: возможно-ли сделать это командой sed в одну
>строку? Вопрос чисто теоретический, призванный глубже понять возможности sed.
>
>В общем-то, в редакторе sed есть команда s///, которая заменяет одно на
>другое. Во второй части команды можно поставить "\1", означающее найденную часть.
>
>Поэтому, к примеру, выделение адреса тривиально:
>
>sed "s/This is address \([0-9A-F]*\)/\1/" file1 > out
>
>Пусть есть некий элементарный скрипт, выполняющий поиск во втором файле и возвращающий
>имя:
>
>script:
>=====================================
>#!/bin/sh
>grep $1 file2 | awk '{print $1}'
>=====================================
>
>Теперь попробуем подставить во вторую часть результат выполнения этого скрипта:
>sed "s/This is address \([0-9A-F]*\)/`./script '\1'`/" file1 > out
>
>Получаем ошибку: "grep: invalid back reference"
>
>В то же время какое-нибудь элементарное эхо работает вполне прилично:
>sed "s/This is address \([0-9A-F]*\)/`echo __'\1'__`/" file1 > out
>
>Получается вот что:
>=====================================
>__000075AF__
>String 1
>String 2
>__0000753D__
>String 1
>String 2
>...
>=====================================
>
>В идеале должно получиться нечто такое:
>sed "s/This is address \([0-9A-F]*\)/`grep '\1' file2 | awk '{print $1}'`/" file1 > out
>
>Пожалуйста, проконсультируйте по вышеописанному. Почему grep не работает, а echo работает?
>Спасибо!
echo и "обратные кавычки" нейтрализуют друг друга. собсно команде echo передается в качестве аргумента \1, буквально. она его выводит, и обратными кавычками \1 "возвращается" в команду sed. т.е. после того, как шелом обработана "вставка" `echo __'\1'__` выполняется команда
sed "s/This is address \([0-9A-F]*\)/__\1__/" file1
и вы видите вроде бы правильный результат. но он неправильный. ибо echo не имела своим аргументом текст, соответствующий \1, а имела лишь строку \1 буквально.
данная команда запускает целый набор процессов, и одним из них является шел, эту команду запустивший. именно шел делает все подстановки по ``. тем не менее про то, что делает sed он не знает, и не имеет доступа к его контексту. а эквивалент для \1 существует лишь в контексте sed.
советую почитать таки man sh (man bash) на тему выяснения, какую именно (немаловажную) роль играет шел в выполнении подобных конструкций. и четко уяснить как именно и какие данные передаются между процессами - участниками при использовании конструкций ``, | (пайплайн), eval итд.

\^P^/

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

2. "Вопрос по использованию sed для редактирования файла"  
Сообщение от Roman K email on 07-Фев-07, 06:34 
>echo и "обратные кавычки" нейтрализуют друг друга. собсно команде echo передается в
>качестве аргумента \1, буквально. она его выводит, и обратными кавычками \1
>"возвращается" в команду sed. т.е. после того, как шелом обработана "вставка"
>`echo __'\1'__` выполняется команда
>sed "s/This is address \([0-9A-F]*\)/__\1__/" file1

Точно! Спасибо большое, что-то меня клинануло :)

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Оцените тред (1=ужас, 5=супер)? [ 1 | 2 | 3 | 4 | 5 ] [Рекомендовать для помещения в FAQ]




Спонсоры:
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2021 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру