2

I have a text file (FILE_A.txt) with this content:

Content1
Content2
Content3

And other text file (FILE_B.txt) with this content:

A[#]
B[#]
C[#]

I would like to combine FILE_A.txt and FILE_B.txt in other file (FILE_C.txt) in this way:

A[Content1]
B[Content2]
C[Content3]

How could I make this using bash shell in linux (sed, cut, grep, etc)?

2
  • I've tried again with diferents contents for FILE_A and FILE_B, and I don't know why it doesn't works. File_B.txt now has "something(#,@);" and File_A.txt has "__OtherTexts". When I try to combine the two files with dogbane method, it copies the content of each line at the end of the lines contained in FILE_B.txt. Any ideas? Commented Dec 12, 2012 at 15:43
  • With my new issue, the ghoti method works fine for me :) Commented Dec 12, 2012 at 15:54

3 Answers 3

3

Here we go.

# awk 'NR==FNR{a[NR]=$0;next;} sub(/#/,a[FNR])' FILE_A.txt FILE_B.txt
A[Content1]
B[Content2]
C[Content3]

How does this work?

  • NR==FNR - causes the following statements to be run if the record number matches the FILE record number - that is, we are currently reading only the firs tfile.
  • {a[NR]=$0;next;} - Store values from the first file in an array.
  • sub(/#/,a[FNR]) - Once we're in the second file, substitute # for the matching value stored from the first file. Note that this isn't inside curly brackets, so it's being evaluated as a condition. If the sub() statement succeeds, the current line is printed.
Sign up to request clarification or add additional context in comments.

1 Comment

No problem, Cesar. The advantage of this also is that because we're using sub() to replace a substring, this solution basically makes the lines of FILE_A.txt into a template for the data in FILE_B.txt. If your requirements become more complex than your sample data, this may be preferable to handling the output from paste.
2

Use paste and sed as follows:

$ paste File_B.txt File_A.txt | sed 's/#]\s*\(.*$\)/\1]/g'
A[Content1]
B[Content2]
C[Content3]

2 Comments

Works in Linux, but the \s makes it non-portable. Won't work in BSD, OSX, Solaris, etc, unless you've installed GNU sed.
@ghoti That's easily fixed. You can change the paste command to use a specific delimiter of your choice (using the -d option) and then use the same delimiter in the sed command instead of the \s*.
2

The following reads both files concurrently, one line at a time, and store the lines in $value and $template. We then use bash's variable substring replacement to replace # within $template with the contents of $value.

exec 6<"FILE_B.txt"  # open file for reading and assign file descriptor 6

while read -r value; do  # loop through FILE_A.txt, storing each line as $value
  read -r template <&6   # read a line from FILE_B.txt, store as $template
  echo ${template/\#/$value}  # replace value into the template in place of `#`
done <"FILE_A.txt"

exec 6<&-  # close input file descriptor 6

1 Comment

Complex but very educational. Thanks for your answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.