Форум русскоязычного сообщества Ubuntu


Увидели сообщение с непонятной ссылкой, спам, непристойность или оскорбление?
Воспользуйтесь ссылкой «Сообщить модератору» рядом с сообщением!

Автор Тема: Замена одной строки на строку из другого файла  (Прочитано 2177 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн dobriivoin

  • Автор темы
  • Новичок
  • *
  • Сообщений: 31
    • Просмотр профиля
Есть файл slkmarc.dat
                  
1                  
020    $c0.00                  
245    $h[Text]                  
1                  
020    $c0.00                  
245    $h[Text]                  
1                  
020    $c0.00                  
245    $a1-$h[Text]                  
1
и есть файл ukmarc.mrk  где
=LDR  00120nam a22000611a 4500         
=020  \\$d0.00
=245  \\$z[Text]   
=LDR  00120nam a22000971a 4500         
=020  \\$d0.00         
=245  \\$z[Text]         
         
Нужно чтоб в первом файле заменялись строки, которые начинаются на "1" на строку =LDR ХХХХХХ  из второго файла. Первая "1" на первое соответствие "=LDR ХХХХХХ" из файла ukmarc.mrk; вторая "1" на второе =LDR ХХХХХХ.  Это марк записи библиотеки. Знаю, что можно сделать это при помощи скриптов, используя awk или sed,  но к сожалению с синтаксисом этих команд не знаком. Вывод можно сделать либо в третий файл, либо заменить все строки  с "1" в первом. Подскажите пожалуйста!

Оффлайн Master_Sergius

  • Активист
  • *
  • Сообщений: 528
  • i3
    • Просмотр профиля
Сложноватая задача для sed и awk, возможно лучше написать скрипт на python? Будет просто и легко
Мой блог о семействе *nix: http://nixtravelling.blogspot.com/

Оффлайн Azure

  • Модератор раздела
  • Старожил
  • *
  • Сообщений: 6017
  • Windows10, i3wm on Debian9, Manjaro20.0
    • Просмотр профиля
Конечно, можно и на python, только кто решил что на bash сложнее?
Код: (bash) [Выделить]
while read line
do
    if [[ "$line" =~ "=LDR " ]]
    then
        sed -i "/^1.*/{s//$line/;q}" slkmarc.dat
    fi
done < ukmarc.mrk
и даже короче:
Код: (bash) [Выделить]
while read line
do
    sed -i "/^1.*/{s//$line/;q}" slkmarc.dat
done < <(sed '/^=LDR /!d' ukmarc.mrk)
или awk
Код: (bash) [Выделить]
awk 'NR==FNR{if(/^=LDR /)a[++i]=$0;next}/^1/{++j;$0=a[j]}1' ukmarc.mrk slkmarc.dat
Пользователь решил продолжить мысль [time]25 Февраль 2015, 10:00:48[/time]:
Или вот еще натолкнули на идею:
Код: (bash) [Выделить]
sed -n 's|=LDR .*|s/(^\|\\n)1\\s*(\\n\|$)/\\1&\\2/|p' ukmarc.mrk | sed -zrf - slkmarc.dat
« Последнее редактирование: 25 Февраля 2015, 11:31:33 от Azure »
В Linux можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн Master_Sergius

  • Активист
  • *
  • Сообщений: 528
  • i3
    • Просмотр профиля
Конечно, можно и на python, только кто решил что на bash сложнее?
Код: (bash) [Выделить]
while read line
do
    if [[ "$line" =~ "=LDR " ]]
    then
        sed -i "/^1.*/{s//$line/;q}" slkmarc.dat
    fi
done < ukmarc.mrk
и даже короче:
Код: (bash) [Выделить]
while read line
do
    sed -i "/^1.*/{s//$line/;q}" slkmarc.dat
done < <(sed '/^=LDR /!d' ukmarc.mrk)
или awk
Код: (bash) [Выделить]
awk 'NR==FNR{if(/^=LDR /)a[++i]=$0;next}/^1/{++j;$0=a[j]}1' ukmarc.mrk slkmarc.dat
Пользователь решил продолжить мысль [time]25 Февраль 2015, 10:00:48[/time]:
Или вот еще натолкнули на идею:
Код: (bash) [Выделить]
sed -n 's|=LDR .*|s/(^\|\\n)1\\s*(\\n\|$)/\\1&\\2/|p' ukmarc.mrk | sed -zrf - slkmarc.dat

Воу-воу, палехче )

Умопомрачительно во всех смыслах! Это круто, что так можно, но разве это понятно простому смертному? нечитабельно, ёп
Мой блог о семействе *nix: http://nixtravelling.blogspot.com/

Оффлайн Azure

  • Модератор раздела
  • Старожил
  • *
  • Сообщений: 6017
  • Windows10, i3wm on Debian9, Manjaro20.0
    • Просмотр профиля
Последние 2 может (хотя довольно просто разобраться) и "нечитабельны", но если и первые — то кто такой этот "простой смертный"?
В Linux можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн Master_Sergius

  • Активист
  • *
  • Сообщений: 528
  • i3
    • Просмотр профиля
Последние 2 может (хотя довольно просто разобраться) и "нечитабельны", но если и первые — то кто такой этот "простой смертный"?

Я :)

Ну ладно, первый понятен, хотя додуматься до такого подхода тоже надо
Мой блог о семействе *nix: http://nixtravelling.blogspot.com/

Оффлайн Azure

  • Модератор раздела
  • Старожил
  • *
  • Сообщений: 6017
  • Windows10, i3wm on Debian9, Manjaro20.0
    • Просмотр профиля
Master_Sergius,
Да ладно прибедняться. Для Вас же на python "просто и легко", значит не все так плохо. Кстати, напишите — сравним.
В Linux можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн Master_Sergius

  • Активист
  • *
  • Сообщений: 528
  • i3
    • Просмотр профиля
Ну, тут ещё можно продолжить мудрить, когда позиции не совпадают, но идут по порядку, а пока рабочий вариант для совпадающих позиций:

import re

PATTERN_IN = '1'
#use this, if it is needed
#PATTERN_OUT = '=LDR.*'

FILE_SOURCE = 'slkmarc.dat'
FILE_REPLACER = 'ukmarc.mrk'
FILE_OUT = 'output.txt'

with open(FILE_SOURCE) as f:
    lines_source = f.readlines()


with open(FILE_REPLACER) as f:
    lines_replacer = f.readlines()

def replace_by_position(lines_source, lines_replacer):
    """
        works only when line numbers are same for both files
    """
    for index, line in enumerate(lines_source):
        if re.match(PATTERN_IN, line.strip()):
            if index < len(lines_replacer):
                lines_source[index] = lines_replacer[index]
            else:
                break

replace_by_position(lines_source, lines_replacer)

with open(FILE_OUT, 'w') as f:
    f.writelines(lines_source)
Мой блог о семействе *nix: http://nixtravelling.blogspot.com/

Оффлайн dobriivoin

  • Автор темы
  • Новичок
  • *
  • Сообщений: 31
    • Просмотр профиля
Помогло awk 'NR==FNR{if(/^=LDR /)a[++i]=$0;next}/^1/{++j;$0=a[j]}1' ukmarc.mrk slkmarc.dat !!!!
 Azure огромное вам спасибо и респект!
Пометку решено пока не ставлю - посмотрю как перекомпилирует МarkEdit измененный файл slkmarc.dat. 

Пользователь решил продолжить мысль [time]26 Февраль 2015, 17:34:32[/time]:
Еще один вопрос. Как можно вставить пустые строки перед каждой строкой, которая начинается на =LDR? Так чтобы пустые строки  разделяли множество записей на блоки?

Пользователь решил продолжить мысль 26 Февраля 2015, 16:47:26:
Вроде нашел ответ.    sed '/regex/{x;p;x;}'
« Последнее редактирование: 26 Февраля 2015, 16:47:26 от dobriivoin »

Оффлайн Azure

  • Модератор раздела
  • Старожил
  • *
  • Сообщений: 6017
  • Windows10, i3wm on Debian9, Manjaro20.0
    • Просмотр профиля
Код: (bash) [Выделить]
sed '/=LDR /i\ '
Код: (bash) [Выделить]
sed "/=LDR /s/^/\n/"
В Linux можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн dobriivoin

  • Автор темы
  • Новичок
  • *
  • Сообщений: 31
    • Просмотр профиля
Всем спасибо за помощь, тему закрываю!!!

 

Страница сгенерирована за 0.018 секунд. Запросов: 21.