0

I recently asked a question very similar to this one but failed to provide enough feedback for what would be a solution for this particular case. Opening this question with further information and context.

I have two files:

File1:

not_keyword: 'something'
keyword: 'condition'
another_not_keyword: 'something'

File2:

condition 1 condition 2 condition 3

I would like to find all occurrences of keyword in File1 and replace its content (condition) with the content of File2.

Desired output in this case:

not_keyword: 'something'
keyword: 'condition 1 condition 2 condition 3'
another_not_keyword: 'something"

It's my intent to have the replacement happen in place (directly on the file itself). A solution using gawk was given, but unfortunately I can't use anything other than sed or awk.

  • Will there always be only one line in file2? – RomanPerekhrest Jan 21 at 16:33
  • @RomanPerekhrest yes. – t988GF Jan 21 at 17:09
1

Awk approach:

awk '$1=="keyword:"{ getline k < "file2"; print $1, "\047" k "\047"; next }1' file1

The output:

not_keyword: 'something'
keyword: 'condition 1 condition 2 condition 3'
another_not_keyword: 'something'

As an alternative use sed in-place substitution:

$ sed -Ei "s/^(keyword: ).*/\1'$(cat file2)'/" file1
|improve this answer|||||
  • This provides the correct output put not directly in the file (in place). Any chance I can do changes in the file without having to use gawk? – t988GF Jan 21 at 18:53
  • @t988GF, have you tried awk '<command>' file1 > tmp1 && mv tmp1 file1 ? – RomanPerekhrest Jan 21 at 19:11
  • @t988GF, see my update – RomanPerekhrest Jan 21 at 19:15
  • Getting -e expression #1, char 81: unknown option to `s' (on GNU sed 4.4) @RomanPerekhrest – t988GF Jan 21 at 19:27
  • the sed script will fail cryptically for various contents of file2, e.g. / or & or \2 or $ or... The awk script with getline has issues too, see awk.freeshell.org/AllAboutGetline, but they're less likely to occur. – Ed Morton Jan 22 at 15:13
1
$ cat tst.awk
NR == FNR {
    new = (NR>1 ? new ORS : "") $0
    next
}
$1 == "keyword:" {
    $0 = $1 OFS "\047" new "\047"
}
{ print }

$ awk -f tst.awk file2 file1
not_keyword: 'something'
keyword: 'condition 1 condition 2 condition 3'
another_not_keyword: 'something'
|improve this answer|||||
  • Thank you Ed, this replaces the text as expect. Would there be a way to make it a bit more "portable", without requiring the .awk file? Also, is it possible to replace inline? As I mentioned in the post using gawk for inline is not possible. – t988GF Feb 10 at 10:51
  • Just do awk 'NR == FNR { new = (NR>1 ? new ORS : "") $0; next } $1 == "keyword:" { $0 = $1 OFS "\047" new "\047" } { print }' file2 file1. When you say "replace inline" - do you mean modify one of the original input files? If so, which one? In any case, you'd just do awk 'script' file > tmp && mv tmp file - that's all that any of the "inplace" editing tools do internally anyway. – Ed Morton Feb 10 at 14:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.