Saturday, May 4, 2024
4
rated 0 times [  4] [ 0]  / answers: 1 / hits: 2604  / 3 Years ago, sat, june 19, 2021, 5:11:15

How can I use bash to replace a string in a file from another file
For example:


There is a path: Hostnameexampleexample.txt
I want to replace the Hostname with 162 hostnames from another file that contains the 162 hostnames then I save the result.
So the total path should be : 162 paths with different hostnames (162)


The first folder is : Paths.txt ( has 2 paths):


Hostnameexample1example1.txt
Hostnameexample2example2.txt

The Second file is: Hostname.txt ( has 162 hostnames )


I tried :


sed -i 's/Hostname/Hostname.txt/gI' Paths.txt

But the result is :


Hostname.txtexample1example1.txt
Hostname.txtexample2example2.txt

It did not read the real hostname inside the file Hostname.txt


More From » command-line

 Answers
6

This is not a straight answer to the question, but to solve this task you can use the following loop:


while IFS= read -r hostname; do 
printf '%sexample1example1.txt
' "$hostname" >> ./hosts-new.txt;
printf '%sexample2example2.txt
' "$hostname" >> ./hosts-new.txt;
done < ./hosts-list.txt

Copy the above lines and run them as a single command (inline script).


Here are some explanations:



  • hosts-new.txt is the output file.



  • hosts-list.txt is the input file containing hostnames, each at new line.



  • IFS= read -r hostname (at each loop's iteration) will read a line of the input file and assign it as a value of the variable that we named $hostname... as @StéphaneChazelas says in his encyclopedic answer this is the canonical way to read one line of input with the read builtin.



    • The key is that read reads words from a (possibly backslash-continued) line, where words are $IFS delimited and backslash can be used to escape the delimiters (or continue lines). So the read command should be tweaked to read lines.



    • IFS= changes the internal field separator to the null string, thus we preserve leading and trailing whitespace in the result.



    • The option -r - raw input - disables interpretation of backslash escapes and line-continuation in the read data (reference).





  • printf '%sexampleexample.txt
    ' "$hostname"
    will generate the desired output for each line. By we are escaping the special meaning of the single . The character
    at the end means new line. %s is a string formatted placeholder of the value of the first positional parameter (of printf) which is our variable $hostname.



  • The output redirection >> will append each line to the output file.



  • By the part < ./hosts-list.txt at the end we are passing the content of the input file as input of the while loop, which is defined by the three keywords while (condition); do (something); done. So while reads the file line by line and, in this case, the condition is while there is an input.






Here is another version of the above, that probably will be faster because it will write to the new file only once after the loop is finished.


while IFS= read -r hostname; do 
printf '%sexample1example1.txt
' "$hostname";
printf '%sexample2example2.txt
' "$hostname";
done < ./hosts-list.txt > ./hosts-new.txt

Note here is used the redirection > (instead of >>) that will override the content of the output file.


[#688] Saturday, June 19, 2021, 3 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
tialmes

Total Points: 14
Total Questions: 108
Total Answers: 102

Location: Oman
Member since Thu, Jun 16, 2022
2 Years ago
tialmes questions
Tue, Feb 7, 23, 19:21, 1 Year ago
Mon, Aug 23, 21, 16:53, 3 Years ago
Tue, May 10, 22, 18:28, 2 Years ago
;