Tesla4o
@Tesla4o
Без пользы жизнь - безвременная смерть... В. Гете

Как как распарсить .rc файл командой sed?

Всем здравствуйте!

Появилась необходимость распарсить виндовые .rc файлы ресурсов от Visual Studio. А если точнее вытащить от туда таблицы строк и записать их в другой .h файл в виде std::map.
Написал bash скрипт без использования sed. Он работает как нужно но очень долго. Так как файлов много и строковых таблиц еще больше. Поэтому решил использовать sed. Но так как я мало пользуюсь bash'ом и командой sed не приходилось пользоваться. Прошу помощи знающих!

Вот пример блока в .rc файле
STRINGTABLE
BEGIN
    IDS_STRING101           "Example string 1"
    IDS_STRING102           "_Example string 3.14"
END

STRINGTABLE
BEGIN
    IDS_STRING103           "Example string 3"
    IDS_STRING104           "_Example string 4"
END


Ключ не обязательно может начинаться на IDS_. Название может быть каким угодно. В IDS_STRING101 может содержать например END (IDS_STRING101_END).
На выходе должно получиться примерно так:
const std::map<unsigned int, std::string> nameMap = {
    {IDS_STRING101, "Example string 1"},
    {IDS_STRING102, "_Example string 3.14"},
    {IDS_STRING103, "_Example string 3"},
    {IDS_STRING103, "Example string 4"},
};


Есть еще проблема. Формат текста в файлах может быть не стандартным.
То есть может выглядеть вот так например:
STRINGTABLE // comment
BEGIN
    IDS_STRING101           "Example string 1"
    IDS_STRING102           
                             "Example string 2"
    END


Получается ключ на одной строке, а значение уже идет на следующей. Или комментарий после тега. Тег END может располагаться не в начале строки.
Конечно это не главная проблема. Потому что можно пройтись ручками поправить все. Но если есть возможность парсить sed'ом то будет большой +.
  • Вопрос задан
  • 76 просмотров
Решения вопроса 1
Tesla4o
@Tesla4o Автор вопроса
Без пользы жизнь - безвременная смерть... В. Гете
Вопрос закрыт.
Оставлю ссылку с решением.

https://stackoverflow.com/questions/74572673/parsi...
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
как-то так ?

echo -E "const std::map<unsigned int, std::string> nameMap = {"; cat /tmp/111.txt | egrep IDS | sed -e 's/\(IDS_STRING[0-9]\{1,\}\)[ ]\{1,\}\(.*\)/\{\1\, \2\},/gp'; echo "};"



Вводный файл
root@Bonus:/tmp# cat 111.txt
STRINGTABLE
BEGIN
    IDS_STRING101           "Example string 1"
    IDS_STRING102           "_Example string 3.14"
END

STRINGTABLE
BEGIN
    IDS_STRING103           "Example string 3"
    IDS_STRING104           "_Example string 4"
END


Вывод
root@Bonus:/tmp# echo -E "const std::map<unsigned int, std::string> nameMap = {"; cat /tmp/111.txt | egrep IDS | sed -e 's/\(IDS_STRING[0-9]\{1,\}\)[ ]\{1,\}\(.*\)/\{\1\, \2\},/gp'; echo
const std::map<unsigned int, std::string> nameMap = {
    {IDS_STRING101, "Example string 1"},
    {IDS_STRING101, "Example string 1"},
    {IDS_STRING102, "_Example string 3.14"},
    {IDS_STRING102, "_Example string 3.14"},
    {IDS_STRING103, "Example string 3"},
    {IDS_STRING103, "Example string 3"},
    {IDS_STRING104, "_Example string 4"},
    {IDS_STRING104, "_Example string 4"},
};
root@Bonus:/tmp#


Собственно по вашему тз.
теперь что касается строк, вы не привели примера этих строк, но их можно выхватить несколькими способами, начиная с банальных cut и awk с соответствующими разделителями, ну и самим сед тоже можно.
За разделитель можно взять первое "
Из пояснений могу добавить что \1 это $1 в синтаксисе седа ;) ну и двойка соответственно $2
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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