Кілька дій пошуку та заміни в одному великому текстовому файлі


11

У мене великий текстовий файл (близько 2 ГБ). Я хочу виконати п'ять дій пошуку та заміни на одному файлі, і я хотів би зробити це в одній команді. Зазвичай я використовую vim, відкриваю файл, роблю одну дію заміни, потім наступну і т. Д. Є один улов, як я помітив, що після трьох-чотирьох пошуків vim завершується через проблеми з пам'яттю.

Ось два приклади команди, яку я використовую у Vim:

:%s/www\.abcdef/www.test.abcdef/g 
:%s/www\.klmnop/www.test.klmnop/g

Який найкращий спосіб впоратися з цим?

Відповіді:


8

Я б користувався sed таким чином:

sed -i "s/www\.abcdef/www.test.abcdef/g;s/www\.kmlnop/www.test.klmnop/g;" yourfile.txt

-iваріант означає заміну "на місці". Ви можете сказати sed, щоб створити резервну копію вашого файлу, надавши розширення на цю опцію ( -i.bakстворить резервну копію yourfile.txt як yourfile.txt.bak).


Це швидко! Не тільки ваша відповідь ;-), але цей сценарій з 5 пошуковими і замінюючими операціями приблизно в 10 разів швидше, ніж просто відкриття файлу в vim. Одна річ мене бентежила. Спочатку я думав, що .bak файл буде відредагованим файлом, але, звичайно, це оригінал.
SPRBRN

Десять дій пошуку та заміни (з тисячами звернень) у файлі об'ємом 2 Гб за один раз, проблем із пам'яттю немає. Менше двох хвилин на середньому робочому столі - супер!
SPRBRN

Одне запитання ... Ви уникаєте крапок у рядку заміни. Це потрібно?
SPRBRN

1
Привітання @rxt :) Насправді ти маєш рацію, ти можеш використовувати непомічені точки в рядку заміни в sed. Я спробував, і це працює. У Unix & Linux Stackexchange є хороший потік , і прийнята відповідь не згадує крапки як символи, які слід втекти.
ssssteffff

2
@rxt Ви сказали, що замініть рядок, вибачте, ні вам не потрібно уникати їх там.
тердон

6

Якщо у вас є багато більше шаблонів пошуку, ви можете зберегти їх у файлі та прочитати звідти заміни. Наприклад, скажіть, що це вміст replacements.txt:

www\.abcdef www.test.abcdef 
www\.klmnop www.test.klmnop

Потім ви можете прочитати список N замін і замінити їх цим:

while read from to; do
  sed -i "s/$from/$to/" infile.txt ; 
done < replacements.txt 

ПРИМІТКИ:

  • Це передбачає, що ваші рядки пошуку не містять пробілів, і будь-які дивні символи потрібно уникати replacements.txt.
  • Він запускається один sedна заміну, що може зайняти деякий час, якщо у вас буде багато операцій по заміні.
  • Він може мати справу з довільною кількістю замін (тисяч чи мільйонів чи що завгодно) до тих пір, поки ви не заперечуєте, що це займе трохи більше часу.

Іншим варіантом було б написати вищезазначене як sedсценарій:

s/www\.abcdef/www\.test\.abcdef/g;
s/www\.kmlnop/www\.test\.klmnop/g;
s/aaaa/bbbb/g;
s/cccc/dddd/g;
s/eeee/ffff/g;

Потім ви можете запустити скрипт у вашому файлі, і він здійснить усі заміни за один раз:

sed -f replace.sed infile.txt 

+1 для ,, інший варіант ''. Може бути зручним, щоб заміни зберігалися у файлі! (Сподіваюсь, я це згадаю ...)
mpy

+1 для "іншого варіанту" ще й тому, що він використовує нативну функціональність, а не користувацький сценарій, тому є більш портативним / доступним для доступу
David Cook

@DavidCook дякую, але він не більш рідний або портативний, ніж інші. Перший підхід - це цикл оболонки POSIX, він точно такий же портативний, як і другий. Це буде просто набагато повільніше, оскільки він використовує петлю оболонки.
тердон

Ви маєте рацію, я мав на увазі те, що формат файлу сценарію sed є більш портативним, оскільки він використовує вбудований функціонал sed, а не скрипт, який повинен бути спільним разом із файлом substituments.txt. Тим не менш, вони обидва чудові варіанти!
Девід Кук
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.