Существуют разные серверы от всех менеджеров доменных имен верхнего уровня, каждый с разными ограничениями. Кроме того, многие из этих управляющих объектов изменяют пределы по отношению к текущей нагрузке на свои серверы. Некоторые из них добавляют немного времени к вашему запрету для каждого отклоненного запроса, некоторые - нет. Это просто сложно сказать.
Некоторые серверы whois, такие как whois.iana.org (который содержит информацию обо всех именах верхнего уровня, таких как «net» и «org»), вообще не ограничивают подключения. Немецкий, как мне сказали, начинает жаловаться после нескольких миллионов запросов. Некоторые из серверов, которые отвечают за менее известные имена верхнего уровня, могут заблокировать ваш доступ только после нескольких сотен запросов.
Если вы достигли предела и заблокированы, это еще не конец света. Вам либо придется ждать, пока ваш запрет будет отменен, либо - если применимо - для изменения вашего IP-адреса. Я бы предположил, что несколько тысяч должны быть в порядке.
Возможно, вам захочется установить задержку в 200 мс между запросами, поэтому они разнесены на несколько минут.
Этот простой скрипт python должен выполнить задачу:
#!/usr/bin/env python
# Syntax: multiline-replace.py input.txt search.txt replacement.txt
import sys
inp = open(sys.argv[1]).read()
needle = open(sys.argv[2]).read()
replacement = open(sys.argv[3]).read()
sys.stdout.write(inp.replace(needle,replacement))
Как и большинство других решений, недостаток состоит в том, что весь файл сразу же удаляется в память. Для небольших текстовых файлов он должен работать достаточно хорошо.
даже если Вы не любите седой [F2] и perl, вы можете по-прежнему найти вкус в серой-templed awk. Этот ответ, кажется, то, что вы ищете. Я воспроизвожу его здесь. Скажем, у вас есть три файла и хотите заменить needle с replacement в haystack:
awk ' BEGIN { RS="" }
FILENAME==ARGV[1] { s=$0 }
FILENAME==ARGV[2] { r=$0 }
FILENAME==ARGV[3] { sub(s,r) ; print }
' needle replacement haystack > output
это не связано с регулярными выражениями и поддерживает символы новой строки. Это похоже на работу с достаточно большими файлами. Оно связано чавкать весь файл в память, поэтому он не будет работать с файлами произвольного размера. Если вы хотите его более элегантным, вы можете приложить всю эту историю в bash-скрипт, или превратить его в awk скрипт.
Даже если вам не нравятся седые sed и perl, вы все равно можете найти симпатию к серому awk. Этот ответ кажется тем, что вы ищете. Я воспроизвожу его здесь. Скажем, у вас есть три файла и вы хотите заменить needle на replacement в haystack:
awk ' BEGIN { RS="" }
FILENAME==ARGV[1] { s=$0 }
FILENAME==ARGV[2] { r=$0 }
FILENAME==ARGV[3] { sub(s,r) ; print }
' needle replacement haystack > output
. Это не связано с регулярными выражениями и поддерживает символы новой строки. Кажется, он работает с достаточно большими файлами. Это связано с разрывом всего файла в памяти, поэтому он не будет работать с файлами произвольного размера. Если вы хотите, чтобы он был более изящным, вы можете вложить весь shebang в сценарий bash или превратить его в скрипт awk.
Этот простой скрипт python должен выполнить задачу:
#!/usr/bin/env python
# Syntax: multiline-replace.py input.txt search.txt replacement.txt
import sys
inp = open(sys.argv[1]).read()
needle = open(sys.argv[2]).read()
replacement = open(sys.argv[3]).read()
sys.stdout.write(inp.replace(needle,replacement))
Как и большинство других решений, недостаток состоит в том, что весь файл сразу же удаляется в память. Для небольших текстовых файлов он должен работать достаточно хорошо.
Даже если вам не нравятся седые sed и perl, вы все равно можете найти симпатию к серому awk. Этот ответ кажется тем, что вы ищете. Я воспроизвожу его здесь. Скажем, у вас есть три файла и вы хотите заменить needle на replacement в haystack:
awk ' BEGIN { RS="" }
FILENAME==ARGV[1] { s=$0 }
FILENAME==ARGV[2] { r=$0 }
FILENAME==ARGV[3] { sub(s,r) ; print }
' needle replacement haystack > output
. Это не связано с регулярными выражениями и поддерживает символы новой строки. Кажется, он работает с достаточно большими файлами. Это связано с разрывом всего файла в памяти, поэтому он не будет работать с файлами произвольного размера. Если вы хотите, чтобы он был более изящным, вы можете вложить весь shebang в сценарий bash или превратить его в скрипт awk.
Даже если вам не нравится седло sed
и perl
, вы все равно можете найти симпатию к серо-образному awk
. Этот ответ кажется тем, что вы ищете. Я воспроизвожу его здесь. Скажем, у вас есть три файла и вы хотите заменить иглу
заменой
в haystack
:
awk 'BEGIN { RS = ""} FILENAME == ARGV [1] {s = $ 0} FILENAME == ARGV [2] {r = $ 0} FILENAME == ARGV [3] {sub (s, r); print} 'output haystack> output
Это не включает регулярные выражения и поддерживает символы новой строки. Кажется, он работает с достаточно большими файлами. Это связано с разрывом всего файла в памяти, поэтому он не будет работать с файлами произвольного размера. Если вы хотите, чтобы он был более изящным, вы можете заключить весь shebang в сценарий bash или превратить его в скрипт awk
.
Даже если вам не нравится седло sed
и perl
, вы все равно можете найти симпатию к серо-образному awk
. Этот ответ кажется тем, что вы ищете. Я воспроизвожу его здесь. Скажем, у вас есть три файла и вы хотите заменить иглу
заменой
в haystack
:
awk 'BEGIN { RS = ""} FILENAME == ARGV [1] {s = $ 0} FILENAME == ARGV [2] {r = $ 0} FILENAME == ARGV [3] {sub (s, r); print} 'output haystack> output
Это не включает регулярные выражения и поддерживает символы новой строки. Кажется, он работает с достаточно большими файлами. Это связано с разрывом всего файла в памяти, поэтому он не будет работать с файлами произвольного размера. Если вы хотите, чтобы он был более изящным, вы можете заключить весь shebang в сценарий bash или превратить его в скрипт awk
.
Этот простой скрипт python должен выполнить задачу:
#! / usr / bin / env python # Синтаксис: multiline-replace.py input.txt search.txt replacement.txt import sys inp = open (sys.argv [1]). read () needle = open (sys.argv [2]). read () replacement = open (sys.argv [3]). read () sys.stdout.write (inp.replace (игла, замена))
Как и большинство других решений, недостаток состоит в том, что весь файл сразу попадает в память. Для небольших текстовых файлов он должен работать достаточно хорошо.
Даже если вам не нравится седло sed
и perl
, вы все равно можете найти симпатию к серо-образному awk
. Этот ответ кажется тем, что вы ищете. Я воспроизвожу его здесь. Скажем, у вас есть три файла и вы хотите заменить иглу
заменой
в haystack
:
awk 'BEGIN { RS = ""} FILENAME == ARGV [1] {s = $ 0} FILENAME == ARGV [2] {r = $ 0} FILENAME == ARGV [3] {sub (s, r); print} 'output haystack> output
Это не включает регулярные выражения и поддерживает символы новой строки. Кажется, он работает с достаточно большими файлами. Это связано с разрывом всего файла в памяти, поэтому он не будет работать с файлами произвольного размера. Если вы хотите, чтобы он был более изящным, вы можете заключить весь shebang в сценарий bash или превратить его в скрипт awk
.
Даже если вам не нравится седло sed
и perl
, вы все равно можете найти симпатию к серо-образному awk
. Этот ответ кажется тем, что вы ищете. Я воспроизвожу его здесь. Скажем, у вас есть три файла и вы хотите заменить иглу
заменой
в haystack
:
awk 'BEGIN { RS = ""} FILENAME == ARGV [1] {s = $ 0} FILENAME == ARGV [2] {r = $ 0} FILENAME == ARGV [3] {sub (s, r); print} 'output haystack> output
Это не включает регулярные выражения и поддерживает символы новой строки. Кажется, он работает с достаточно большими файлами. Это связано с разрывом всего файла в памяти, поэтому он не будет работать с файлами произвольного размера. Если вы хотите, чтобы он был более изящным, вы можете заключить весь shebang в сценарий bash или превратить его в скрипт awk
.
[
, (
и ложные результаты на $
, ^
(не нашли данные, даже хотя он был идентичен) ... Я больше не проверял ... (Но команда выглядит «правильно» и :)
– Peter.O
9 January 2011 в 20:56
gsub
представляется более подходящим, чем sub
. Мне кажется странным, что не появилась простая утилита поиска / замены mulitline nonregex. Кажется, что нет простого способа ускользания / цитирования поисковой иглы (в perl
, например, с помощью quotemeta
).
– loevborg
9 January 2011 в 21:43
grep -F --fixed-strings
. Это ставит grep в совершенно новую категорию (для меня) ... как read -r
... буквальная интерпретация .. Если бы это было sed
, это было бы все очень просто .. (возможно, awk
имеет что-то вроде этого (?) .... и btw. Простейшая часть всего этого заключается в замене строк: простая head (после идентификации первого номера строки) | замена кошки | хвост остальное (длина удаленной части известна) ... Итак, теперь с grep -F -A {num}
это может быть сшито скоро :)
– Peter.O
9 January 2011 в 22:26
Этот простой скрипт python должен выполнить задачу:
#! / usr / bin / env python # Синтаксис: multiline-replace.py input.txt search.txt replacement.txt import sys inp = open (sys.argv [1]). read () needle = open (sys.argv [2]). read () replacement = open (sys.argv [3]). read () sys.stdout.write (inp.replace (игла, замена))
Как и большинство других решений, недостаток состоит в том, что весь файл сразу попадает в память. Для небольших текстовых файлов он должен работать достаточно хорошо.
Следующий фрагмент заменяет новые строки с помощью труб, выполняет замену и сворачивает разделители обратно. Утилита может захлебываться, если линия видна очень долго. Вы можете выбрать любой символ для обмена, если он не находится в вашей строке поиска.
<old.txt tr '\n' '|' |
sed 's/\(|\|^\)'\''Twas … toves|Did … Bandersnatch!'\''|/new line 1|new line 2|/g' |
tr '|' '\n' >new.txt
Поддержка Awk и perl, поддерживающая два или более пустые строки в качестве разделителя записей. С awk передайте -vRS= (пустая переменная RS). С помощью Perl пройдите -000 («режим абзаца») или установите $,="". Это не полезно здесь, так как у вас есть строка поиска с несколькими пунктами.
Awk и perl также поддерживают установку любой строки в качестве разделителя записей. Установите RS или $, на любую строку, которая не находится в вашей строке поиска.
<old.txt perl -pe '
BEGIN {$, = "|"}
s/^'\''Twas … toves\nDid … Bandersnatch!'\''$/new line 1\nnew line 2/mg
' >new.txt
Некоторые утилиты легко позволяют вам читать весь файл в память и работать над ним.
<old.txt perl -0777 -pe '
s/^'\''Twas … toves\nDid … Bandersnatch!'\''$/new line 1\nnew line 2/mg
' >new.txt
Прочитайте строки один за другим. Начните с пустого буфера. Если вы видите строку «Twas» и буфер пуст, поместите ее в буфер. Если вы видите «Did gyre» и есть одна строка в буфере, добавьте текущую строку в буфер и так далее. Если вы только что добавили строку «Bandersnatch», выведите заменяющий текст. Если текущая строка не попала в буфер, напечатайте содержимое буфера, распечатайте текущую строку и очистите буфер.
psusi показывает реализацию sed. В sed концепция буфера встроена; это называется удерживающим пространством. В awk или perl вы просто используете переменную (возможно, две, одну для содержимого буфера и одну для количества строк).
Я был уверен, что должен был быть способ сделать это с sed. После некоторого googling я наткнулся на это:
http://austinmatzko.com/2008/04/26/sed-multi-line-search-and-replace/
Основано на что я закончил писать:
sed -n '1h;1!H;${;g;s/foo\nbar/jar\nhead/g;p;}' < x
Что правильно взяло содержимое x:
foo bar
И выплюнуть :
jar head
Даже если вам не нравятся седые sed и perl, вы все равно можете найти симпатию к серому awk. Этот ответ кажется тем, что вы ищете. Я воспроизвожу его здесь. Скажем, у вас есть три файла и вы хотите заменить needle на replacement в haystack:
awk ' BEGIN { RS="" }
FILENAME==ARGV[1] { s=$0 }
FILENAME==ARGV[2] { r=$0 }
FILENAME==ARGV[3] { sub(s,r) ; print }
' needle replacement haystack > output
. Это не связано с регулярными выражениями и поддерживает символы новой строки. Кажется, он работает с достаточно большими файлами. Это связано с разрывом всего файла в памяти, поэтому он не будет работать с файлами произвольного размера. Если вы хотите, чтобы он был более изящным, вы можете вложить весь shebang в сценарий bash или превратить его в скрипт awk.
UPDATE: скрипт python от loevborg, безусловно, является самым простым и лучшим решением (в этом нет никаких сомнений), и я очень доволен этим, но я хотел бы указать, что сценарий bash, который я представил (в конце вопрос) нигде не так сложно, как кажется. Я урезал всю отладочную ветвь, которую я использовал для ее проверки .. и здесь она снова не имеет перегруженности (для тех, кто посещает эту страницу). Это в основном sed однострочный с предварительным и пост-шестнадцатеричным преобразованиями:
F=("$haystack" "$needle" "$replacement")
for f in "${F[@]}" ; do cat "$f" | hexdump -v -e '1/1 "%02x"' > "$f.hex" ; done
sed -i "s/$(cat "${F[1])}.hex")/$(cat "${F[2])}.hex")/p" "${F[0])}.hex"
cat "${F[0])}.hex" | xxd -r -p > "${F[0])}"
# delete the temp *.hex files.
Просто, чтобы бросить шляпу в кольцо, я придумал решение «sed» который не столкнется с проблемами с UPDATE символами регулярных выражений, потому что он использует не один! .. вместо этого он работает с Hexdumped версиями файлов ...
Я думаю, что он слишком «тяжелый», но он работает и, по-видимому, не ограничен ограничениями на размер. GNU sed имеет неограниченный размер буфера шаблонов, и вот где заканчивается блок строк поиска Hexdumped. Так что в этом отношении все в порядке ...
Я все еще ищу шаблон потому что он будет более гибким в отношении белого пространства (и я бы ожидал, быстрее) ... но до этого .. Это знаменитый мистер Сед. :)
Этот скрипт полностью запущен как есть, и разумно прокомментирован ... Он выглядит больше, чем он есть; У меня всего 7 строк кода. Для полуреалистичного теста он загружает книгу «Алиса через зазеркалье» из Project Gutenberg (363.1 KB) ... и заменяет оригинальное стихотворение Jabberwocky собственной версией строки .. (Интересно, что это не так много другое чтение его назад :)
PS. Я просто понял, что слабость в этом методе заключается в том, что ваш оригинал использует \ r \ n (0xODOA) в качестве новой строки, а ваш «текст в соответствии» сохраняется с помощью \ n (0x0A) .. тогда этот процесс сопоставления мертв вода ... («diff» не имеет таких проблем) ...
# In a text file, replace one block of lines with another block
#
# Keeping with the 'Jabberwocky' theme,
# and using 'sed' with 'hexdump', so
# there is no possible *special* char clash.
#
# The current setup will replace only the first instance.
# Using sed's 'g' command, it cah change all instances.
#
lookinglass="$HOME/Through the Looking-Glass by Lewis Carroll"
jabberwocky="$lookinglass (jabberwocky)"
ykcowrebbaj="$lookinglass (ykcowrebbaj)"
##### This section if FOR TEST PREPARATION ONLY
fromURL="http://www.gutenberg.org/ebooks/12.txt.utf8"
wget $fromURL -O "$lookinglass"
if (($?==0))
then echo "Download OK"
else exit 1
fi
# Make a backup of the original (while testing)
cp "$lookinglass" "$lookinglass(fromURL)"
#
# Extact the poem and write it to a file. (It runs from line 322-359)
sed -n 322,359p "$lookinglass" > "$jabberwocky"
cat "$jabberwocky"; read -p "This is the original.. (press Enter to continue)"
#
# Make a file containing a replacement block of lines
tac "$jabberwocky" > "$ykcowrebbaj"
cat "$ykcowrebbaj"; read -p "This is the REPLACEMENT.. (press Enter to continue)"
##### End TEST PREPARATION
# The main process
#
# Make 'hexdump' versions of the 3 files... source, expected, replacement
cat "$lookinglass" | hexdump -v -e '1/1 "%02x"' > "$lookinglass.xdig"
cat "$jabberwocky" | hexdump -v -e '1/1 "%02x"' > "$jabberwocky.xdig"
cat "$ykcowrebbaj" | hexdump -v -e '1/1 "%02x"' > "$ykcowrebbaj.xdig"
# Now use 'sed' in a safe (no special chrs) way.
# Note, all files are now each, a single line ('\n' is now '0A')
sed -i "s/$(cat "$jabberwocky.xdig")/$(cat "$ykcowrebbaj.xdig")/p" "$lookinglass.xdig"
##### This section if FOR CHECKING THE RESULTS ONLY
# Check result 1
read -p "About to test for the presence of 'jabberwocky.xdig' within itself (Enter) "
sed -n "/$(cat "$jabberwocky.xdig")/p" "$jabberwocky.xdig"
echo -e "\n\nA dump above this line, means: 'jabberwocky' is as expected\n"
# Check result 2
read -p "About to test for the presence of 'ykcowrebbaj.xdig' within itself (Enter) "
sed -n "/$(cat "$ykcowrebbaj.xdig")/p" "$ykcowrebbaj.xdig"
echo -e "\n\nA dump above this line, means: 'ykcowrebbaj' is as expected\n"
# Check result 3
read -p "About to test for the presence of 'lookinglass.xdig' within itself (Enter) "
sed -n "/$(cat "$ykcowrebbaj.xdig")/p" "$lookinglass.xdig"
echo -e "\n\nA dump above this line, means: 'lookinglass' is as expected\n"
# Check result 4
read -p "About to test for the presence of 'lookinglass.xdig' within itself (Enter) "
sed -n "/$(cat "$jabberwocky.xdig")/p" "$lookinglass.xdig"
echo -e "\n\nNo dump above this line means: 'lookinglass' is as expected\n"
##### End of CHECKING THE RESULTS
# Now convert the hexdump to binary, and overwrite the original
cat "$lookinglass.xdig" | xxd -r -p > "$lookinglass"
# Echo the "modified" poem to the screen
sed -n 322,359p "$lookinglass"
echo -e "\n\nYou are now looking at the REPLACEMENT text (dumped directly from the source 'book'"
в следующих ОСП фрагмент строки с трубами, выполняет замена и разделители переключает обратно. Программа может подавиться, если строки он видит крайне долго. Вы можете выбрать любого персонажа, чтобы поменяться с тех пор, как он не в строку поиска.
<old.txt tr '\n' '|' |
sed 's/\(|\|^\)'\''Twas … toves|Did … Bandersnatch!'\''|/new line 1|new line 2|/g' |
tr '|' '\n' >new.txt
поддержка на awk и Perl установка двух или более пустые строки как разделитель записей. С awk, пройти -vRS= (пустой RS переменная). С Perl, пройти -000 (“пункт режим”) или установите для параметра $,="". Это не полезно, вот хоть у тебя есть мульти-пункт строку поиска.
на awk и Perl также поддерживает установку любой строки как разделитель записей. Установить нажать [F8] и [F9] и любую строку, а не в строку поиска.
<old.txt perl -pe '
BEGIN {$, = "|"}
s/^'\''Twas … toves\nDid … Bandersnatch!'\''$/new line 1\nnew line 2/mg
' >new.txt
некоторые утилиты позволят вам легко считывать весь файл в память и работать на нем.
<old.txt perl -0777 -pe '
s/^'\''Twas … toves\nDid … Bandersnatch!'\''$/new line 1\nnew line 2/mg
' >new.txt
читать по одной линии. Начинать с пустого буфера. Если вы видите “линия тва” и буфер пуст, поместить его в буфер. Если вы видите “сделал круговращение” и там одна строка в буфер, добавить текущую строку в буфер, и так далее. Если вы только что добавленный строке “Брандашмыг”, вывод текста замены. Если текущая строка не идут в буфер, распечатать содержимое буфера, печать текущую строку и пустой буфер.
psusi показывает внедрение СЭД. В СЭД, буфер концепция встроенные; это называется трюм. В awk или Perl, вы бы просто использовать переменную (возможно два, один за содержимое буфера и один для нескольких строк).
я был уверен, что там должен быть способ сделать это с помощью sed. После некоторых погуглив я наткнулся на это:
http://austinmatzko.com/2008/04/26/sed-multi-line-search-and-replace/
основан на том, что я закончил писать:
sed -n '1h;1!H;${;g;s/foo\nbar/jar\nhead/g;p;}' < x
, который правильно взял содержимое x:
Василий Пупкин
и выплюнул:
лысая голова
даже если Вы не любите седой [F2] и perl, вы можете по-прежнему найти вкус в серой-templed awk. Этот ответ, кажется, то, что вы ищете. Я воспроизвожу его здесь. Скажем, у вас есть три файла и хотите заменить needle с replacement в haystack:
awk ' BEGIN { RS="" }
FILENAME==ARGV[1] { s=$0 }
FILENAME==ARGV[2] { r=$0 }
FILENAME==ARGV[3] { sub(s,r) ; print }
' needle replacement haystack > output
это не связано с регулярными выражениями и поддерживает символы новой строки. Это похоже на работу с достаточно большими файлами. Оно связано чавкать весь файл в память, поэтому он не будет работать с файлами произвольного размера. Если вы хотите его более элегантным, вы можете приложить всю эту историю в bash-скрипт, или превратить его в awk скрипт.
UPDATE: скрипт python от loevborg, безусловно, является самым простым и лучшим решением (в этом нет никаких сомнений), и я очень доволен этим, но я хотел бы указать, что сценарий bash, который я представил (в конце вопрос) нигде не так сложно, как кажется. Я урезал всю отладочную ветвь, которую я использовал для ее проверки .. и здесь она снова не имеет перегруженности (для тех, кто посещает эту страницу). Это в основном sed однострочный с предварительным и пост-шестнадцатеричным преобразованиями:
F=("$haystack" "$needle" "$replacement")
for f in "${F[@]}" ; do cat "$f" | hexdump -v -e '1/1 "%02x"' > "$f.hex" ; done
sed -i "s/$(cat "${F[1])}.hex")/$(cat "${F[2])}.hex")/p" "${F[0])}.hex"
cat "${F[0])}.hex" | xxd -r -p > "${F[0])}"
# delete the temp *.hex files.
Просто, чтобы бросить шляпу в кольцо, я придумал решение «sed» который не столкнется с проблемами с UPDATE символами регулярных выражений, потому что он использует не один! .. вместо этого он работает с Hexdumped версиями файлов ...
Я думаю, что он слишком «тяжелый», но он работает и, по-видимому, не ограничен ограничениями на размер. GNU sed имеет неограниченный размер буфера шаблонов, и вот где заканчивается блок строк поиска Hexdumped. Так что в этом отношении все в порядке ...
Я все еще ищу шаблон потому что он будет более гибким в отношении белого пространства (и я бы ожидал, быстрее) ... но до этого .. Это знаменитый мистер Сед. :)
Этот скрипт полностью запущен как есть, и разумно прокомментирован ... Он выглядит больше, чем он есть; У меня всего 7 строк кода. Для полуреалистичного теста он загружает книгу «Алиса через зазеркалье» из Project Gutenberg (363.1 KB) ... и заменяет оригинальное стихотворение Jabberwocky собственной версией строки .. (Интересно, что это не так много другое чтение его назад :)
PS. Я просто понял, что слабость в этом методе заключается в том, что ваш оригинал использует \ r \ n (0xODOA) в качестве новой строки, а ваш «текст в соответствии» сохраняется с помощью \ n (0x0A) .. тогда этот процесс сопоставления мертв вода ... («diff» не имеет таких проблем) ...
# In a text file, replace one block of lines with another block
#
# Keeping with the 'Jabberwocky' theme,
# and using 'sed' with 'hexdump', so
# there is no possible *special* char clash.
#
# The current setup will replace only the first instance.
# Using sed's 'g' command, it cah change all instances.
#
lookinglass="$HOME/Through the Looking-Glass by Lewis Carroll"
jabberwocky="$lookinglass (jabberwocky)"
ykcowrebbaj="$lookinglass (ykcowrebbaj)"
##### This section if FOR TEST PREPARATION ONLY
fromURL="http://www.gutenberg.org/ebooks/12.txt.utf8"
wget $fromURL -O "$lookinglass"
if (($?==0))
then echo "Download OK"
else exit 1
fi
# Make a backup of the original (while testing)
cp "$lookinglass" "$lookinglass(fromURL)"
#
# Extact the poem and write it to a file. (It runs from line 322-359)
sed -n 322,359p "$lookinglass" > "$jabberwocky"
cat "$jabberwocky"; read -p "This is the original.. (press Enter to continue)"
#
# Make a file containing a replacement block of lines
tac "$jabberwocky" > "$ykcowrebbaj"
cat "$ykcowrebbaj"; read -p "This is the REPLACEMENT.. (press Enter to continue)"
##### End TEST PREPARATION
# The main process
#
# Make 'hexdump' versions of the 3 files... source, expected, replacement
cat "$lookinglass" | hexdump -v -e '1/1 "%02x"' > "$lookinglass.xdig"
cat "$jabberwocky" | hexdump -v -e '1/1 "%02x"' > "$jabberwocky.xdig"
cat "$ykcowrebbaj" | hexdump -v -e '1/1 "%02x"' > "$ykcowrebbaj.xdig"
# Now use 'sed' in a safe (no special chrs) way.
# Note, all files are now each, a single line ('\n' is now '0A')
sed -i "s/$(cat "$jabberwocky.xdig")/$(cat "$ykcowrebbaj.xdig")/p" "$lookinglass.xdig"
##### This section if FOR CHECKING THE RESULTS ONLY
# Check result 1
read -p "About to test for the presence of 'jabberwocky.xdig' within itself (Enter) "
sed -n "/$(cat "$jabberwocky.xdig")/p" "$jabberwocky.xdig"
echo -e "\n\nA dump above this line, means: 'jabberwocky' is as expected\n"
# Check result 2
read -p "About to test for the presence of 'ykcowrebbaj.xdig' within itself (Enter) "
sed -n "/$(cat "$ykcowrebbaj.xdig")/p" "$ykcowrebbaj.xdig"
echo -e "\n\nA dump above this line, means: 'ykcowrebbaj' is as expected\n"
# Check result 3
read -p "About to test for the presence of 'lookinglass.xdig' within itself (Enter) "
sed -n "/$(cat "$ykcowrebbaj.xdig")/p" "$lookinglass.xdig"
echo -e "\n\nA dump above this line, means: 'lookinglass' is as expected\n"
# Check result 4
read -p "About to test for the presence of 'lookinglass.xdig' within itself (Enter) "
sed -n "/$(cat "$jabberwocky.xdig")/p" "$lookinglass.xdig"
echo -e "\n\nNo dump above this line means: 'lookinglass' is as expected\n"
##### End of CHECKING THE RESULTS
# Now convert the hexdump to binary, and overwrite the original
cat "$lookinglass.xdig" | xxd -r -p > "$lookinglass"
# Echo the "modified" poem to the screen
sed -n 322,359p "$lookinglass"
echo -e "\n\nYou are now looking at the REPLACEMENT text (dumped directly from the source 'book'"
Следующий фрагмент заменяет новые строки с помощью труб, выполняет замену и сворачивает разделители обратно. Утилита может захлебываться, если линия видна очень долго. Вы можете выбрать любой символ для обмена, если он не находится в вашей строке поиска.
<old.txt tr '\n' '|' |
sed 's/\(|\|^\)'\''Twas … toves|Did … Bandersnatch!'\''|/new line 1|new line 2|/g' |
tr '|' '\n' >new.txt
Поддержка Awk и perl, поддерживающая два или более пустые строки в качестве разделителя записей. С awk передайте -vRS= (пустая переменная RS). С помощью Perl пройдите -000 («режим абзаца») или установите $,="". Это не полезно здесь, так как у вас есть строка поиска с несколькими пунктами.
Awk и perl также поддерживают установку любой строки в качестве разделителя записей. Установите RS или $, на любую строку, которая не находится в вашей строке поиска.
<old.txt perl -pe '
BEGIN {$, = "|"}
s/^'\''Twas … toves\nDid … Bandersnatch!'\''$/new line 1\nnew line 2/mg
' >new.txt
Некоторые утилиты легко позволяют вам читать весь файл в память и работать над ним.
<old.txt perl -0777 -pe '
s/^'\''Twas … toves\nDid … Bandersnatch!'\''$/new line 1\nnew line 2/mg
' >new.txt
Прочитайте строки один за другим. Начните с пустого буфера. Если вы видите строку «Twas» и буфер пуст, поместите ее в буфер. Если вы видите «Did gyre» и есть одна строка в буфере, добавьте текущую строку в буфер и так далее. Если вы только что добавили строку «Bandersnatch», выведите заменяющий текст. Если текущая строка не попала в буфер, напечатайте содержимое буфера, распечатайте текущую строку и очистите буфер.
psusi показывает реализацию sed. В sed концепция буфера встроена; это называется удерживающим пространством. В awk или perl вы просто используете переменную (возможно, две, одну для содержимого буфера и одну для количества строк).
я был уверен, что там должен быть способ сделать это с помощью sed. После некоторых погуглив я наткнулся на это:
http://austinmatzko.com/2008/04/26/sed-multi-line-search-and-replace/
основан на том, что я закончил писать:
sed -n '1h;1!H;${;g;s/foo\nbar/jar\nhead/g;p;}' < x
, который правильно взял содержимое x:
Василий Пупкин
и выплюнул:
лысая голова
обновление: loevborg это скрипт на языке Python-это, конечно, самое простое и лучшее решение (нет сомнений) и я очень счастлива с ним, но я хотел бы отметить, что баш скрипт я представил (в конце вопрос) не так сложно, как кажется.. я обрезал все отладки шлак, который я использовал, чтобы проверить его.. и вот он снова без вскрыши (для кого посещение этой страницы).. это в основном sed один-лайнер, С до и после наговора-преобразования :
F=("$haystack" "$needle" "$replacement")
for f in "${F[@]}" ; do cat "$f" | hexdump -v -e '1/1 "%02x"' > "$f.hex" ; done
sed -i "s/$(cat "${F[1])}.hex")/$(cat "${F[2])}.hex")/p" "${F[0])}.hex"
cat "${F[0])}.hex" | xxd -r -p > "${F[0])}"
# delete the temp *.hex files.
просто, чтобы бросить свою шляпу на ринг, я придумал решение СЭД, по которым не возникнут какие-либо проблемы с обновлением символы регулярных выражений, потому что он использует даже не одного! .. вместо этого он работает на Hexdumped версии файлов...
я думаю, что это слишком "тяжелой", но он работает, и, видимо, не ограничен каким-либо ограничений по размеру.. ГНУ СЭД имеет неограниченный узор Размер буфера, и именно там, где Hexdumped блок поиска строк заканчивается.. так что все нормально в этом отношении...
я все еще ищу шаблон решение, потому что он будет более гибким в отношении пробела (и я бы ожидать; быстрее)... но пока.. это знаменитый мистер СЭД. :)
этот скрипт полностью работает, и разумно сказала, что... она кажется больше, что это; я только 7 строк базовый код. Для полу-реалистичный тест, он скачивает книги "Алиса в Зазеркалье" из проекта "Гутенберг" (363.1 КБ) ... и заменяет оригинальный Бармаглот стихотворение со строкой-перевернутая версия.. (интересно, это не сильно отличается прочитав его задом наперед :)
ПС. Я просто поняла, что слабость в этом методе-это если оригинал использует \р\н (0xODOA), так как это символ новой строки, и свой "текст, чтобы соответствовать" сохраняется с \п (0x0A).. потом этот процесс сопоставления является мертвым в воде... ('различия' нет таких проблем) ...
# In a text file, replace one block of lines with another block
#
# Keeping with the 'Jabberwocky' theme,
# and using 'sed' with 'hexdump', so
# there is no possible *special* char clash.
#
# The current setup will replace only the first instance.
# Using sed's 'g' command, it cah change all instances.
#
lookinglass="$HOME/Through the Looking-Glass by Lewis Carroll"
jabberwocky="$lookinglass (jabberwocky)"
ykcowrebbaj="$lookinglass (ykcowrebbaj)"
##### This section if FOR TEST PREPARATION ONLY
fromURL="http://www.gutenberg.org/ebooks/12.txt.utf8"
wget $fromURL -O "$lookinglass"
if (($?==0))
then echo "Download OK"
else exit 1
fi
# Make a backup of the original (while testing)
cp "$lookinglass" "$lookinglass(fromURL)"
#
# Extact the poem and write it to a file. (It runs from line 322-359)
sed -n 322,359p "$lookinglass" > "$jabberwocky"
cat "$jabberwocky"; read -p "This is the original.. (press Enter to continue)"
#
# Make a file containing a replacement block of lines
tac "$jabberwocky" > "$ykcowrebbaj"
cat "$ykcowrebbaj"; read -p "This is the REPLACEMENT.. (press Enter to continue)"
##### End TEST PREPARATION
# The main process
#
# Make 'hexdump' versions of the 3 files... source, expected, replacement
cat "$lookinglass" | hexdump -v -e '1/1 "%02x"' > "$lookinglass.xdig"
cat "$jabberwocky" | hexdump -v -e '1/1 "%02x"' > "$jabberwocky.xdig"
cat "$ykcowrebbaj" | hexdump -v -e '1/1 "%02x"' > "$ykcowrebbaj.xdig"
# Now use 'sed' in a safe (no special chrs) way.
# Note, all files are now each, a single line ('\n' is now '0A')
sed -i "s/$(cat "$jabberwocky.xdig")/$(cat "$ykcowrebbaj.xdig")/p" "$lookinglass.xdig"
##### This section if FOR CHECKING THE RESULTS ONLY
# Check result 1
read -p "About to test for the presence of 'jabberwocky.xdig' within itself (Enter) "
sed -n "/$(cat "$jabberwocky.xdig")/p" "$jabberwocky.xdig"
echo -e "\n\nA dump above this line, means: 'jabberwocky' is as expected\n"
# Check result 2
read -p "About to test for the presence of 'ykcowrebbaj.xdig' within itself (Enter) "
sed -n "/$(cat "$ykcowrebbaj.xdig")/p" "$ykcowrebbaj.xdig"
echo -e "\n\nA dump above this line, means: 'ykcowrebbaj' is as expected\n"
# Check result 3
read -p "About to test for the presence of 'lookinglass.xdig' within itself (Enter) "
sed -n "/$(cat "$ykcowrebbaj.xdig")/p" "$lookinglass.xdig"
echo -e "\n\nA dump above this line, means: 'lookinglass' is as expected\n"
# Check result 4
read -p "About to test for the presence of 'lookinglass.xdig' within itself (Enter) "
sed -n "/$(cat "$jabberwocky.xdig")/p" "$lookinglass.xdig"
echo -e "\n\nNo dump above this line means: 'lookinglass' is as expected\n"
##### End of CHECKING THE RESULTS
# Now convert the hexdump to binary, and overwrite the original
cat "$lookinglass.xdig" | xxd -r -p > "$lookinglass"
# Echo the "modified" poem to the screen
sed -n 322,359p "$lookinglass"
echo -e "\n\nYou are now looking at the REPLACEMENT text (dumped directly from the source 'book'"
в следующих ОСП фрагмент строки с трубами, выполняет замена и разделители переключает обратно. Программа может подавиться, если строки он видит крайне долго. Вы можете выбрать любого персонажа, чтобы поменяться с тех пор, как он не в строку поиска.
<old.txt tr '\n' '|' |
sed 's/\(|\|^\)'\''Twas … toves|Did … Bandersnatch!'\''|/new line 1|new line 2|/g' |
tr '|' '\n' >new.txt
поддержка на awk и Perl установка двух или более пустые строки как разделитель записей. С awk, пройти -vRS= (пустой RS переменная). С Perl, пройти -000 (“пункт режим”) или установите для параметра $,="". Это не полезно, вот хоть у тебя есть мульти-пункт строку поиска.
на awk и Perl также поддерживает установку любой строки как разделитель записей. Установить нажать [F8] и [F9] и любую строку, а не в строку поиска.
<old.txt perl -pe '
BEGIN {$, = "|"}
s/^'\''Twas … toves\nDid … Bandersnatch!'\''$/new line 1\nnew line 2/mg
' >new.txt
некоторые утилиты позволят вам легко считывать весь файл в память и работать на нем.
<old.txt perl -0777 -pe '
s/^'\''Twas … toves\nDid … Bandersnatch!'\''$/new line 1\nnew line 2/mg
' >new.txt
читать по одной линии. Начинать с пустого буфера. Если вы видите “линия тва” и буфер пуст, поместить его в буфер. Если вы видите “сделал круговращение” и там одна строка в буфер, добавить текущую строку в буфер, и так далее. Если вы только что добавленный строке “Брандашмыг”, вывод текста замены. Если текущая строка не идут в буфер, распечатать содержимое буфера, печать текущую строку и пустой буфер.
psusi показывает внедрение СЭД. В СЭД, буфер концепция встроенные; это называется трюм. В awk или Perl, вы бы просто использовать переменную (возможно два, один за содержимое буфера и один для нескольких строк).
Я был уверен, что должен был быть способ сделать это с sed. После некоторого googling я наткнулся на это:
http://austinmatzko.com/2008/04/26/sed-multi-line-search-and-replace/
Основано на что я закончил писать:
sed -n '1h;1!H;${;g;s/foo\nbar/jar\nhead/g;p;}' < x
Что правильно взяло содержимое x:
foo bar
И выплюнуть :
jar head
UPDATE: скрипт python от loevborg, безусловно, является самым простым и лучшим решением (в этом нет никаких сомнений), и я очень доволен этим, но я хотел бы указать, что сценарий bash, который я представил (в конце вопрос) нигде не так сложно, как кажется. Я урезал всю отладочную ветвь, которую я использовал для ее проверки .. и здесь она снова не имеет перегруженности (для тех, кто посещает эту страницу). Это в основном sed однострочный с предварительным и пост-шестнадцатеричным преобразованиями:
F=("$haystack" "$needle" "$replacement")
for f in "${F[@]}" ; do cat "$f" | hexdump -v -e '1/1 "%02x"' > "$f.hex" ; done
sed -i "s/$(cat "${F[1])}.hex")/$(cat "${F[2])}.hex")/p" "${F[0])}.hex"
cat "${F[0])}.hex" | xxd -r -p > "${F[0])}"
# delete the temp *.hex files.
Просто, чтобы бросить шляпу в кольцо, я придумал решение «sed» который не столкнется с проблемами с UPDATE символами регулярных выражений, потому что он использует не один! .. вместо этого он работает с Hexdumped версиями файлов ...
Я думаю, что он слишком «тяжелый», но он работает и, по-видимому, не ограничен ограничениями на размер. GNU sed имеет неограниченный размер буфера шаблонов, и вот где заканчивается блок строк поиска Hexdumped. Так что в этом отношении все в порядке ...
Я все еще ищу шаблон потому что он будет более гибким в отношении белого пространства (и я бы ожидал, быстрее) ... но до этого .. Это знаменитый мистер Сед. :)
Этот скрипт полностью запущен как есть, и разумно прокомментирован ... Он выглядит больше, чем он есть; У меня всего 7 строк кода. Для полуреалистичного теста он загружает книгу «Алиса через зазеркалье» из Project Gutenberg (363.1 KB) ... и заменяет оригинальное стихотворение Jabberwocky собственной версией строки .. (Интересно, что это не так много другое чтение его назад :)
PS. Я просто понял, что слабость в этом методе заключается в том, что ваш оригинал использует \ r \ n (0xODOA) в качестве новой строки, а ваш «текст в соответствии» сохраняется с помощью \ n (0x0A) .. тогда этот процесс сопоставления мертв вода ... («diff» не имеет таких проблем) ...
# In a text file, replace one block of lines with another block
#
# Keeping with the 'Jabberwocky' theme,
# and using 'sed' with 'hexdump', so
# there is no possible *special* char clash.
#
# The current setup will replace only the first instance.
# Using sed's 'g' command, it cah change all instances.
#
lookinglass="$HOME/Through the Looking-Glass by Lewis Carroll"
jabberwocky="$lookinglass (jabberwocky)"
ykcowrebbaj="$lookinglass (ykcowrebbaj)"
##### This section if FOR TEST PREPARATION ONLY
fromURL="http://www.gutenberg.org/ebooks/12.txt.utf8"
wget $fromURL -O "$lookinglass"
if (($?==0))
then echo "Download OK"
else exit 1
fi
# Make a backup of the original (while testing)
cp "$lookinglass" "$lookinglass(fromURL)"
#
# Extact the poem and write it to a file. (It runs from line 322-359)
sed -n 322,359p "$lookinglass" > "$jabberwocky"
cat "$jabberwocky"; read -p "This is the original.. (press Enter to continue)"
#
# Make a file containing a replacement block of lines
tac "$jabberwocky" > "$ykcowrebbaj"
cat "$ykcowrebbaj"; read -p "This is the REPLACEMENT.. (press Enter to continue)"
##### End TEST PREPARATION
# The main process
#
# Make 'hexdump' versions of the 3 files... source, expected, replacement
cat "$lookinglass" | hexdump -v -e '1/1 "%02x"' > "$lookinglass.xdig"
cat "$jabberwocky" | hexdump -v -e '1/1 "%02x"' > "$jabberwocky.xdig"
cat "$ykcowrebbaj" | hexdump -v -e '1/1 "%02x"' > "$ykcowrebbaj.xdig"
# Now use 'sed' in a safe (no special chrs) way.
# Note, all files are now each, a single line ('\n' is now '0A')
sed -i "s/$(cat "$jabberwocky.xdig")/$(cat "$ykcowrebbaj.xdig")/p" "$lookinglass.xdig"
##### This section if FOR CHECKING THE RESULTS ONLY
# Check result 1
read -p "About to test for the presence of 'jabberwocky.xdig' within itself (Enter) "
sed -n "/$(cat "$jabberwocky.xdig")/p" "$jabberwocky.xdig"
echo -e "\n\nA dump above this line, means: 'jabberwocky' is as expected\n"
# Check result 2
read -p "About to test for the presence of 'ykcowrebbaj.xdig' within itself (Enter) "
sed -n "/$(cat "$ykcowrebbaj.xdig")/p" "$ykcowrebbaj.xdig"
echo -e "\n\nA dump above this line, means: 'ykcowrebbaj' is as expected\n"
# Check result 3
read -p "About to test for the presence of 'lookinglass.xdig' within itself (Enter) "
sed -n "/$(cat "$ykcowrebbaj.xdig")/p" "$lookinglass.xdig"
echo -e "\n\nA dump above this line, means: 'lookinglass' is as expected\n"
# Check result 4
read -p "About to test for the presence of 'lookinglass.xdig' within itself (Enter) "
sed -n "/$(cat "$jabberwocky.xdig")/p" "$lookinglass.xdig"
echo -e "\n\nNo dump above this line means: 'lookinglass' is as expected\n"
##### End of CHECKING THE RESULTS
# Now convert the hexdump to binary, and overwrite the original
cat "$lookinglass.xdig" | xxd -r -p > "$lookinglass"
# Echo the "modified" poem to the screen
sed -n 322,359p "$lookinglass"
echo -e "\n\nYou are now looking at the REPLACEMENT text (dumped directly from the source 'book'"
Следующий фрагмент заменяет новые строки с помощью труб, выполняет замену и сворачивает разделители обратно. Утилита может захлебываться, если линия видна очень долго. Вы можете выбрать любой символ для обмена, если он не находится в вашей строке поиска.
<old.txt tr '\n' '|' |
sed 's/\(|\|^\)'\''Twas … toves|Did … Bandersnatch!'\''|/new line 1|new line 2|/g' |
tr '|' '\n' >new.txt
Поддержка Awk и perl, поддерживающая два или более пустые строки в качестве разделителя записей. С awk передайте -vRS= (пустая переменная RS). С помощью Perl пройдите -000 («режим абзаца») или установите $,="". Это не полезно здесь, так как у вас есть строка поиска с несколькими пунктами.
Awk и perl также поддерживают установку любой строки в качестве разделителя записей. Установите RS или $, на любую строку, которая не находится в вашей строке поиска.
<old.txt perl -pe '
BEGIN {$, = "|"}
s/^'\''Twas … toves\nDid … Bandersnatch!'\''$/new line 1\nnew line 2/mg
' >new.txt
Некоторые утилиты легко позволяют вам читать весь файл в память и работать над ним.
<old.txt perl -0777 -pe '
s/^'\''Twas … toves\nDid … Bandersnatch!'\''$/new line 1\nnew line 2/mg
' >new.txt
Прочитайте строки один за другим. Начните с пустого буфера. Если вы видите строку «Twas» и буфер пуст, поместите ее в буфер. Если вы видите «Did gyre» и есть одна строка в буфере, добавьте текущую строку в буфер и так далее. Если вы только что добавили строку «Bandersnatch», выведите заменяющий текст. Если текущая строка не попала в буфер, напечатайте содержимое буфера, распечатайте текущую строку и очистите буфер.
psusi показывает реализацию sed. В sed концепция буфера встроена; это называется удерживающим пространством. В awk или perl вы просто используете переменную (возможно, две, одну для содержимого буфера и одну для количества строк).
я был уверен, что там должен быть способ сделать это с помощью sed. После некоторых погуглив я наткнулся на это:
http://austinmatzko.com/2008/04/26/sed-multi-line-search-and-replace/
основан на том, что я закончил писать:
sed -n '1h;1!H;${;g;s/foo\nbar/jar\nhead/g;p;}' < x
, который правильно взял содержимое x:
Василий Пупкин
и выплюнул:
лысая голова
даже если Вы не любите седой [F2] и perl, вы можете по-прежнему найти вкус в серой-templed awk. Этот ответ, кажется, то, что вы ищете. Я воспроизвожу его здесь. Скажем, у вас есть три файла и хотите заменить needle с replacement в haystack:
awk ' BEGIN { RS="" }
FILENAME==ARGV[1] { s=$0 }
FILENAME==ARGV[2] { r=$0 }
FILENAME==ARGV[3] { sub(s,r) ; print }
' needle replacement haystack > output
это не связано с регулярными выражениями и поддерживает символы новой строки. Это похоже на работу с достаточно большими файлами. Оно связано чавкать весь файл в память, поэтому он не будет работать с файлами произвольного размера. Если вы хотите его более элегантным, вы можете приложить всю эту историю в bash-скрипт, или превратить его в awk скрипт.
UPDATE: скрипт python от loevborg, безусловно, является самым простым и лучшим решением (в этом нет никаких сомнений), и я очень доволен этим, но я хотел бы указать, что сценарий bash, который я представил (в конце вопрос) нигде не так сложно, как кажется. Я урезал всю отладочную ветвь, которую я использовал для ее проверки .. и здесь она снова не имеет перегруженности (для тех, кто посещает эту страницу). Это в основном sed однострочный с предварительным и пост-шестнадцатеричным преобразованиями:
F=("$haystack" "$needle" "$replacement")
for f in "${F[@]}" ; do cat "$f" | hexdump -v -e '1/1 "%02x"' > "$f.hex" ; done
sed -i "s/$(cat "${F[1])}.hex")/$(cat "${F[2])}.hex")/p" "${F[0])}.hex"
cat "${F[0])}.hex" | xxd -r -p > "${F[0])}"
# delete the temp *.hex files.
Просто, чтобы бросить шляпу в кольцо, я придумал решение «sed» который не столкнется с проблемами с UPDATE символами регулярных выражений, потому что он использует не один! .. вместо этого он работает с Hexdumped версиями файлов ...
Я думаю, что он слишком «тяжелый», но он работает и, по-видимому, не ограничен ограничениями на размер. GNU sed имеет неограниченный размер буфера шаблонов, и вот где заканчивается блок строк поиска Hexdumped. Так что в этом отношении все в порядке ...
Я все еще ищу шаблон потому что он будет более гибким в отношении белого пространства (и я бы ожидал, быстрее) ... но до этого .. Это знаменитый мистер Сед. :)
Этот скрипт полностью запущен как есть, и разумно прокомментирован ... Он выглядит больше, чем он есть; У меня всего 7 строк кода. Для полуреалистичного теста он загружает книгу «Алиса через зазеркалье» из Project Gutenberg (363.1 KB) ... и заменяет оригинальное стихотворение Jabberwocky собственной версией строки .. (Интересно, что это не так много другое чтение его назад :)
PS. Я просто понял, что слабость в этом методе заключается в том, что ваш оригинал использует \ r \ n (0xODOA) в качестве новой строки, а ваш «текст в соответствии» сохраняется с помощью \ n (0x0A) .. тогда этот процесс сопоставления мертв вода ... («diff» не имеет таких проблем) ...
# In a text file, replace one block of lines with another block
#
# Keeping with the 'Jabberwocky' theme,
# and using 'sed' with 'hexdump', so
# there is no possible *special* char clash.
#
# The current setup will replace only the first instance.
# Using sed's 'g' command, it cah change all instances.
#
lookinglass="$HOME/Through the Looking-Glass by Lewis Carroll"
jabberwocky="$lookinglass (jabberwocky)"
ykcowrebbaj="$lookinglass (ykcowrebbaj)"
##### This section if FOR TEST PREPARATION ONLY
fromURL="http://www.gutenberg.org/ebooks/12.txt.utf8"
wget $fromURL -O "$lookinglass"
if (($?==0))
then echo "Download OK"
else exit 1
fi
# Make a backup of the original (while testing)
cp "$lookinglass" "$lookinglass(fromURL)"
#
# Extact the poem and write it to a file. (It runs from line 322-359)
sed -n 322,359p "$lookinglass" > "$jabberwocky"
cat "$jabberwocky"; read -p "This is the original.. (press Enter to continue)"
#
# Make a file containing a replacement block of lines
tac "$jabberwocky" > "$ykcowrebbaj"
cat "$ykcowrebbaj"; read -p "This is the REPLACEMENT.. (press Enter to continue)"
##### End TEST PREPARATION
# The main process
#
# Make 'hexdump' versions of the 3 files... source, expected, replacement
cat "$lookinglass" | hexdump -v -e '1/1 "%02x"' > "$lookinglass.xdig"
cat "$jabberwocky" | hexdump -v -e '1/1 "%02x"' > "$jabberwocky.xdig"
cat "$ykcowrebbaj" | hexdump -v -e '1/1 "%02x"' > "$ykcowrebbaj.xdig"
# Now use 'sed' in a safe (no special chrs) way.
# Note, all files are now each, a single line ('\n' is now '0A')
sed -i "s/$(cat "$jabberwocky.xdig")/$(cat "$ykcowrebbaj.xdig")/p" "$lookinglass.xdig"
##### This section if FOR CHECKING THE RESULTS ONLY
# Check result 1
read -p "About to test for the presence of 'jabberwocky.xdig' within itself (Enter) "
sed -n "/$(cat "$jabberwocky.xdig")/p" "$jabberwocky.xdig"
echo -e "\n\nA dump above this line, means: 'jabberwocky' is as expected\n"
# Check result 2
read -p "About to test for the presence of 'ykcowrebbaj.xdig' within itself (Enter) "
sed -n "/$(cat "$ykcowrebbaj.xdig")/p" "$ykcowrebbaj.xdig"
echo -e "\n\nA dump above this line, means: 'ykcowrebbaj' is as expected\n"
# Check result 3
read -p "About to test for the presence of 'lookinglass.xdig' within itself (Enter) "
sed -n "/$(cat "$ykcowrebbaj.xdig")/p" "$lookinglass.xdig"
echo -e "\n\nA dump above this line, means: 'lookinglass' is as expected\n"
# Check result 4
read -p "About to test for the presence of 'lookinglass.xdig' within itself (Enter) "
sed -n "/$(cat "$jabberwocky.xdig")/p" "$lookinglass.xdig"
echo -e "\n\nNo dump above this line means: 'lookinglass' is as expected\n"
##### End of CHECKING THE RESULTS
# Now convert the hexdump to binary, and overwrite the original
cat "$lookinglass.xdig" | xxd -r -p > "$lookinglass"
# Echo the "modified" poem to the screen
sed -n 322,359p "$lookinglass"
echo -e "\n\nYou are now looking at the REPLACEMENT text (dumped directly from the source 'book'"
Следующий фрагмент заменяет новые строки с помощью труб, выполняет замену и сворачивает разделители обратно. Утилита может захлебываться, если линия видна очень долго. Вы можете выбрать любой символ для обмена, если он не находится в вашей строке поиска.
<old.txt tr '\n' '|' |
sed 's/\(|\|^\)'\''Twas … toves|Did … Bandersnatch!'\''|/new line 1|new line 2|/g' |
tr '|' '\n' >new.txt
Поддержка Awk и perl, поддерживающая два или более пустые строки в качестве разделителя записей. С awk передайте -vRS= (пустая переменная RS). С помощью Perl пройдите -000 («режим абзаца») или установите $,="". Это не полезно здесь, так как у вас есть строка поиска с несколькими пунктами.
Awk и perl также поддерживают установку любой строки в качестве разделителя записей. Установите RS или $, на любую строку, которая не находится в вашей строке поиска.
<old.txt perl -pe '
BEGIN {$, = "|"}
s/^'\''Twas … toves\nDid … Bandersnatch!'\''$/new line 1\nnew line 2/mg
' >new.txt
Некоторые утилиты легко позволяют вам читать весь файл в память и работать над ним.
<old.txt perl -0777 -pe '
s/^'\''Twas … toves\nDid … Bandersnatch!'\''$/new line 1\nnew line 2/mg
' >new.txt
Прочитайте строки один за другим. Начните с пустого буфера. Если вы видите строку «Twas» и буфер пуст, поместите ее в буфер. Если вы видите «Did gyre» и есть одна строка в буфере, добавьте текущую строку в буфер и так далее. Если вы только что добавили строку «Bandersnatch», выведите заменяющий текст. Если текущая строка не попала в буфер, напечатайте содержимое буфера, распечатайте текущую строку и очистите буфер.
psusi показывает реализацию sed. В sed концепция буфера встроена; это называется удерживающим пространством. В awk или perl вы просто используете переменную (возможно, две, одну для содержимого буфера и одну для количества строк).