2

I have two files. The fist file is an existing C/C++ source file (*.cpp). The second is a text file (*.txt) and contains one function. The function is in both files, and it needs to be copied from the second file (*.txt) to the first file (*.cpp). The function is also rather long (890+ lines), so copy/paste is a bit unwieldy.

I have a sed command to capture the function in the first file (*.cpp):

ifile=blake2.cpp.old
ofile=blake2.cpp
ffile=blake2-neon.txt
sed -n '/^static void BLAKE2_NEON_Compress64(/,/^}$/p' < $ifile > $ofile

What I don't know is how to tell sed to replace the text it has captured. I've tried to work through the GNU sed manual, but I'm not having much luck. One of the first things to do is drop the /p.

How do I tell sed to replace the block of text it finds with the text from another file?


I found a similar question at How to replace text between two markers in a file with a section of text from another file? but I don't quite follow whats going on, especially since the question is tagged sed but the answers are provided for ed.


The reason I am trying to script this is: its a port of IA-32 SSE to ARM NEON. I have a script that performs the basic substitutions. After a change, I need to copy the updated function to the source code, scp the code to a device, and then compile it. Lather, rinse, repeat. The manual copy/paste of a 1000 line function at each iteration consumes time better spent on other things.

5
  • Wouldn't an #include of the .txt file work, if you scp the latter as well? May 9, 2016 at 5:08
  • stackoverflow.com/questions/16715373/… try sed "/^static void BLAKE2_NEON_Compress64(/,/^}$/ r $ffile" < $ifile > $ofile and then delete the original line using another sed command
    – Sundeep
    May 9, 2016 at 5:12
  • Thanks again @spasic - switching from Appl'e sed to gsed fixed the address problem. However, there's something wrong with the suggestion. The source file with the manual copy/paste is 4800 lines long. After the suggestion, its 4276052 lines long.
    – user56041
    May 9, 2016 at 5:26
  • what exactly went wrong? see the difference between manual one and one with sed.. maybe the line got matched multiple times?
    – Sundeep
    May 9, 2016 at 5:43
  • also, check out unix.stackexchange.com/questions/20322/…
    – Sundeep
    May 9, 2016 at 5:58

1 Answer 1

1

Try something like this. Match the start of the function, use the read command r to read in the text file. Then add a command to delete d all lines between the start and end of the function:

sed '
/^static void BLAKE2_NEON_Compress64(/r '"$ffile"'
/^static void BLAKE2_NEON_Compress64(/,/^}$/d
' <"$ifile" >"$ofile"

If the string to replace is on a single line you can try this

uuid='c0e4e6b2-81f4-477c-89a4-7656e58719ce'
sed '/^'"$uuid"'/{
 r '"$ffile"'
 d
}' <"$ifile" >"$ofile"
3
  • I changed the source file to use a 1-line UUID to make it easier on sed. Could you show the sed to read a C++ source file with a UUID in it (normally, this will cause a compile failure), replace the UUID with the text from another file, and write the modified stream to a new C++ source file? It seems like it should be easy (modify your example), but I'm not getting the damn expected results on OS X 10.8. sed keeps modifying the C++ source file with a UUID, rather than writing to a new file.
    – user56041
    May 9, 2016 at 9:27
  • I'm not sure how sed can edit a file unless you use -i to edit in place. Perhaps you could edit your original question with your new version. I have edited my answer with what I think you wanted. Note I quoted the filenames this time as otherwise this can cause errors when there are special characters in the filenames.
    – meuh
    May 9, 2016 at 9:39
  • Yes, its working fine using the UUID. The script had two variables crossed at the end, and it cause the read and write of files in the quasi-wrong order.
    – user56041
    May 9, 2016 at 11:40

You must log in to answer this question.