Assuming you want to ONLY change blocks of text that match EXACTLY the block shown in your question and that your input always looks exactly as shown in your question then using any POSIX awk you could do:
$ cat tst.sh #!/usr/bin/env bash IFS= read -r -d '' old <<-' !' <type>TRANS</type> <attributes/> <specification_method>rep_name</specification_method> <trans_object_id/> <filename/> <transname>\File Name</transname> ! IFS= read -r -d '' new <<-' !' <type>TRANS</type> <attributes/> <specification_method>rep_name</specification_method> <trans_object_id/> <filename>FILE_PATH/File Name</filename> <transname/> ! old="$old" new="$new" \ awk ' { rec = (NR>1 ? rec ORS : "") $0 } END { old = ENVIRON["old"] new = ENVIRON["new"] # Escape any possible regexp metachars in "old" and # any possible backreference metachars in "new": gsub( /[^^\\]/ , "[&]", old) gsub( /\^/ , "\\^", old) gsub( /\\/ , "\\\\", old) gsub( /&/ , "\\&", new) # Replace every "old" with "new": gsub( old, new, rec ) print rec } ' "${@:--}"
For example, given the following input where the 3rd block is the OPs target from the question and there are other similar-looking blocks that should not be changed as they aren't exactly the OPs target block:
$ cat file <type>CONST</type> <attributes/> <specification_method>rep_name</specification_method> <trans_object_id/> <filename/> <transname>\File Name</transname> <type>TRANS</type> <attributes/> <specification_method>rep_name</specification_method> <trans_object_id/> <filename/> <transname>Foo Bar</transname> <type>TRANS</type> <attributes/> <specification_method>rep_name</specification_method> <trans_object_id/> <filename/> <transname>\File Name</transname> <type>TRANS</type> <attributes/> <specification_method>other rep_name</specification_method> <trans_object_id/> <filename/> <transname>\File Name</transname> <type>TRANS</type> <attributes/> <specification_method>rep_name</specification_method> <trans_object_id/> <filename>final<filename/> <transname>\File Name</transname>
$ ./tst.sh file <type>CONST</type> <attributes/> <specification_method>rep_name</specification_method> <trans_object_id/> <filename/> <transname>\File Name</transname> <type>TRANS</type> <attributes/> <specification_method>rep_name</specification_method> <trans_object_id/> <filename/> <transname>Foo Bar</transname> <type>TRANS</type> <attributes/> <specification_method>rep_name</specification_method> <trans_object_id/> <filename>FILE_PATH/File Name</filename> <transname/> <type>TRANS</type> <attributes/> <specification_method>other rep_name</specification_method> <trans_object_id/> <filename/> <transname>\File Name</transname> <type>TRANS</type> <attributes/> <specification_method>rep_name</specification_method> <trans_object_id/> <filename>final<filename/> <transname>\File Name</transname>
Note that ONLY the 3rd block, the target one, has changed and only the desired lines within that block have changed. That's easier to see using diff between the input file and the command output:
$ diff file <(./tst.sh file) 17,18c17,18 < <filename/> < <transname>\File Name</transname> --- > <filename>FILE_PATH/File Name</filename> > <transname/>
$ diff -y file <(./tst.sh file) <type>CONST</type> <type>CONST</type> <attributes/> <attributes/> <specification_method>rep_name</specification_method> <specification_method>rep_name</specification_method> <trans_object_id/> <trans_object_id/> <filename/> <filename/> <transname>\File Name</transname> <transname>\File Name</transname> <type>TRANS</type> <type>TRANS</type> <attributes/> <attributes/> <specification_method>rep_name</specification_method> <specification_method>rep_name</specification_method> <trans_object_id/> <trans_object_id/> <filename/> <filename/> <transname>Foo Bar</transname> <transname>Foo Bar</transname> <type>TRANS</type> <type>TRANS</type> <attributes/> <attributes/> <specification_method>rep_name</specification_method> <specification_method>rep_name</specification_method> <trans_object_id/> <trans_object_id/> <filename/> | <filename>FILE_PATH/File Name</filename> <transname>\File Name</transname> | <transname/> <type>TRANS</type> <type>TRANS</type> <attributes/> <attributes/> <specification_method>other rep_name</specification_method> <specification_method>other rep_name</specification_method> <trans_object_id/> <trans_object_id/> <filename/> <filename/> <transname>\File Name</transname> <transname>\File Name</transname> <type>TRANS</type> <type>TRANS</type> <attributes/> <attributes/> <specification_method>rep_name</specification_method> <specification_method>rep_name</specification_method> <trans_object_id/> <trans_object_id/> <filename>final<filename/> <filename>final<filename/> <transname>\File Name</transname> <transname>\File Name</transname>
Regarding the here-documents, the space before the ! in the delimiters is 4 blanks and the space at the start of each line inside each here-doc is a tab.
See:
With GNU awk you can replace the contents of the input file by using awk -i inplace '...' or, as with any tool, you can just create/use your own temp file:
tmp=$(mktemp) && trap 'rm -f "$tmp"; exit' EXIT && awk '...' "$1" > "$tmp" && mv -- "$tmp" "$1"
sedis fundamentally a line editor. It has options for holding part of a pattern space for later use, but that syntax is somewhat inflexible, and quickly gets out of hand. If you have coaxedawkinto breaking up the stanzas and repairing the lines, it should be trivial to update the file inawkat the same time. Maybe post theawkyou have so far, and we can provide the final steps.<transname>\File Name</transname>into<filename>FILE_PATH/File Name</filename>(e.g. in a different type of block or a differentFILE Nameor a block with a<type>that isn'tTRANS, etc.? If so, please edit your question to include those cases in your sample input/output. Replacing the desired text is always much easier than not replacing similar text you do NOT want to be replaced so it's important to include the latter in examples.