-1

Say I have a file called before.txt which reads:

1  
2  
3  
4

but want to replace the number 4 with a number (in order) from a text file called after.txt. How would I do so?

after.txt contains:

2743
3028
2850
1092
etc.

Could this be turned into a script as well? If so, I would like it to cycle through all the strings from after.txt in order, and replace the string 4 as said above.

  • Is "2743" the only content in after.txt? – jasonwryan Oct 10 '16 at 5:59
  • No, there are multiple strings. If possible I would like the script to cycle through them all one at a time. (Thanks for the edit btw) – Chance Oct 10 '16 at 6:04
  • Please edit your question to include a sample of after.txt so people know exactly what they are dealing with. – jasonwryan Oct 10 '16 at 6:07
  • So you want as many different result files as lines in after.txt? In other words, loop over each line as explained e.g. here? – dirkt Oct 10 '16 at 6:20
  • Whats your desired output? – heemayl Oct 10 '16 at 7:01
0

Given these files:

cat before.txt 
1  
2  
3  
4
1  
1  
2  
3  
4
2  
3  
4

cat after.txt
2743
3028
2850
1092

And this little script:

#!/bin/bash

while read -r line; do
    if [[ "$line"  == 4 ]]; then
        sed -n '1p' after.txt
        sed -i".bup" '1d' after.txt 
    else
        echo "$line"
    fi  
done < before.txt

I get this result:

./script.sh 
1
2
3
2743
1
1
2
3
3028
2
3
2850

I am sure there is an awk oneliner that can do this, but I don't speak awk fluently! Also, if you want to replace ("in place") the file before.txt, you will have to change the sed statements in the loop. Otherwise you can simply redirect STDOUT to a new file. I choose to print everything to STDOUT in this example for easy viewing.


Tested under OS X 10.11.6 and BSD sed

  • No problem. But please read the comments. Next time, it would be appreciated if you posted your desired output, as well as a sample of what you have tried. Best regards! – maulinglawns Oct 10 '16 at 9:46
1
awk '/^4$/&&getline<"after.txt"||1' before.txt

If the current record $0 is exactly the text 4, then get the next line from after.txt. If that is successful, it becomes $0 and getline returns 1, so the expression is true and the default {print} action is triggered.

If the record is not 4, or getline returns 0 at the EOF of after.txt, the ||1 ensures that we still print the current record. $0 is unmodified if reading after.txt fails.

If getline fails with a -1, we still print $0, since that is a nonzero return code.

0

Something like this in awk ?

$ awk 'NR==FNR{Arr[NR]=$0;next}{if($0==4){i++;print Arr[i]}else{print}}' after.txt before.txt
1
2
3
2743
1
1
2
3
3028
2
3
2850

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.