shellfiltersedwhile-loop

sed to rebuild a manifest from a 2nd file


I'd like to replace a file content for some lines (not all of them) matching another file content:

File1 is a manifest with this format (thousands of lines):

...    
f 755 myself mygroup /opt/app/fileabc a991a508b1166fb14448f303bba7662287b7a827f3761f
f 555 myself mygroup /opt/app/filedef 3bba766209dcd21a0793190b287b7a8a508b1114448f30
...

The last part being sha256sum of the file referenced just ahead. I recompute and recalculate sha256sum for some of these files, ending up in File2:

...
645278b945d6b52c48a1851765c72a8eb1e7030c5ee /opt/app/fileabc
1765c72a8eb1e703aa3ac3ba01d2160c0c83df464ee /opt/app/filedef
...

with the same filename obviously, but a different sha256sum. File1 is 1k lines big, while File2 has only 155 lines updates to present.

How can I make file1 updated with the contents of file2? This command ends up in 155k lines, with many times the same lines added, and not even with the expected replacements:

while read sha file; do
    sed "s;$file (\w+);$file $sha;" file1
done <file2

Solution

  • This might be what you're trying to do, using any awk:

    $ awk 'NR==FNR{ sha[$2]=$1; next } $5 in sha{ $6=sha[$5] } 1' file2 file1
    f 755 myself mygroup /opt/app/fileabc 645278b945d6b52c48a1851765c72a8eb1e7030c5ee
    f 555 myself mygroup /opt/app/filedef 1765c72a8eb1e703aa3ac3ba01d2160c0c83df464ee
    

    The above assumes there are no spaces in your file names or anywhere else except where shown in your example.