2015-06-16 2 views
1

У меня есть около 50 больших текстовых файлов (~ 4 ГБ), и мне нужно только заменить одну строку, расположенную в первых 100 строках этих файлов. На самом деле мне нужна командная строка unix, которая ищет первое совпадение, заменяет его на месте и прерывает.Sed заменить первое появление на месте большими файлами

Я пробовал играть с sed, но я все еще изо всех сил стараюсь получить удовлетворительный результат.

+0

Somehowr related: [Как редактировать текстовый файл 300 ГБ (данные геномики)?] (Http://stackoverflow.com/q/16900721/1983854). – fedorqui

+0

Также несколько сходен [Редактировать огромный файл данных SQL] (http://stackoverflow.com/questions/30727191). Этот файл содержит около 23 гигабайт на машине с 20 ГБ свободного места. –

ответ

4

Вы можете редактировать до первого матча с использованием sed:

sed -e '1,/pattern/{s/pattern/replace/;}' 

В строках 1 до N-1 (где линия N содержит образец), замена ничего не делает; на линии N, это делает реальную работу. После этого вы больше не находитесь в диапазоне строк 1,/pattern/, поэтому дальнейших преобразований не происходит.

Обратите внимание, что это не работает, если строка 1 соответствует шаблону; он затем вносит изменения в строку 1 и следующую строку, соответствующую шаблону. По крайней мере, с GNU sed вы можете изменить 1 на 0, и это работает нормально.

printf "%s\n" pattern pattern pattern pattern | 
sed -e '0,/pattern/{s/pattern/replace/;}' 

Однако описание говорит «в первые 100 строк» ​​и в то время как линия 1 находится в первых 100 строк, что это не так, как вы обычно описывают его, когда он появляется на линии 1.

Вы можете добавить опцию -i, чтобы перезаписать исходный файл после его проверки. Остерегайтесь: не все версии sed поддерживают -i, а в Mac OS X суффикс резервного копирования является обязательным -i.bak (но может быть пустым: используйте -i ''). В отличие от этого, GNU sed имеет дополнительный суффикс, который должен быть присоединен к опции -i.Следовательно, -i.bak работает как с GNU, так и с Mac (BSD) sed; другое использование опции -i относится к варианту sed, который вы используете.

1
sed -i '1,100 { :a; N; $! ba; s/input/output/ }' file 
  • :a; N; $! ba является добавление первые 100 строк в пространстве шаблонов
  • все 100 строки будут рассматриваться как одна строка.
  • Тогда замена будет заботиться только о первом совпадающем шаблоне.
  • -i является INPLACE редактированию

q не могут быть использованы после замены, так как он будет остановить печать остальных линий.

Также перед выполнением выше СЭД я буду рекомендовать проверять это образец строки внутри файла и где с

sed -n '/patternstring/{=;p}' file 

где = это номер строки печати (некоторые Grep стиле СЕПГ команда)

или если вы хотите бросить imidiatelly после обнаружения первого матча

sed -n '/patternstring/{=;p;q}' file 
+0

Я просто попробовал это на 500-строчном вводе, и это не имело никакого эффекта. Что странно, потому что я ожидал совершенно другой режим отказа. –

+0

Позвольте мне проверить на практике, нужно что-то еще + в добавлении 100 строк – josifoski

+0

Теперь он должен работать, я добавил $! который всегда будет правдой, поэтому первые 100 строк будут добавляться – josifoski

1

Если вы хотите обработать первое вхождение, не зная точно, где это, вы могли бы использовать ed. Это очень старый редактор строк, написанный в то время, когда памяти было мало. Это может быть немного менее эффективно, чем sed здесь, но и более прост и более устойчив к тому, что pattent не был точно там, где ожидалось.

echo '/input/s/input/output/ 
wq' | ed file 
Смежные вопросы