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'"