1

file1.txt is like:

$view->name = '12483291';
...
$view->human_name = '12483291';

Also I have some numbers in file2:

8789
53416
673425

What I need to do is: for each number in the above column, replace the '12483291' value, and create a new file named after the replacement number.

Desired output:

file: 8789.inc

$view->name = '8789'
...
$view->human_name = '8789'

file: 53416.inc

$view->name = '53416'
...
$view->human_name = '53416'

file: 673425.inc

$view->name = '673425'
...
$view->human_name = '673425'

How would you approach this?

A few of my attempts, but without getting the result I want:

sed "s/12483291/$(cat file2)/" file1 > 8789.inc

The above works if file2 has only one line, and I have to run the command as many times as the values in file2, manually giving the name of the result file.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • 1
    Welcome to Stack Overflow! Sorry, this is not the way StackOverflow works. Questions of the form "I want to do X, please give me tips and/or sample code" are considered off-topic. Please visit the [help] and read [ask], and especially read [Why is "Can someone help me?" not an actual question?](https://meta.stackoverflow.com/q/284236) – kvantour Sep 21 '20 at 09:39
  • 1
    should i post here what i have tried and did not work? all my attempts or just one? –  Sep 21 '20 at 09:40
  • There are about 1000 ways to do this. The easiest is probably a simple bash loop with a sed on top. No need to fire up python. You could also do this in awk, but it is a bit overkill. – kvantour Sep 21 '20 at 09:41
  • Just update your question by clicking [edit] (below your question, next to your name) and post one or two methods that did not work for you and why they did not work. – kvantour Sep 21 '20 at 09:42
  • Try the following: `while read -r n; do sed "s/'12483291'/'${n}'/g" file.inc > "${n}.inc"; done < list.txt` – kvantour Sep 21 '20 at 09:51
  • the files are named like 12044236^M.inc and $view->name = '12483291'; has become ';iew->name = '12044236 why is this happening? i have used your above suggested command. The list.txt is created on windows, i wonder if this the problem –  Sep 21 '20 at 10:33
  • does `cat -v file1` show up `^M` at the end of the line? If so, see https://stackoverflow.com/questions/45772525/why-does-my-tool-output-overwrite-itself-and-how-do-i-fix-it – Sundeep Sep 21 '20 at 10:48
  • you are totally correct, so many things to learn... –  Sep 21 '20 at 10:54

2 Answers2

2

This might work for you (GNU sed):

sed -n 's/.*/sed "s#12483291#&#g" file1 >&.inc/e' file2

Replace the number 1248329 in the template file1 by each number in file2 and name the file produced by that number with .inc appended.

potong
  • 55,640
  • 6
  • 51
  • 83
1

If your file has dos-style line ending, see Why does my tool output overwrite itself and how do I fix it? first.


With GNU awk

awk -v q="'" -v s="'12483291'" 'NR==FNR{a[$1]; next}
    {for(k in a) {print gensub(s, q k q, 1) > k".inc"}}' f2 f1
  • -v q="'" just a handy variable with single quote character
  • -v s="'12483291'" the field value to be replaced
  • NR==FNR{a[$1]; next} here NR has overall record number and FNR has current file record number. So, NR==FNR will be true only for first file. The array a will store the first field as keys.
  • for(k in a) for the second file, loop over all the keys in array a
    • gensub(s, q k q, 1) change the field value with value of the key (note that this will replace only first match and assumes s doesn't have any regex metacharacter)
    • output of gensub is then redirected to a filename based on the key
  • Add -v RS='\r\n' to handle dos-style input


With other awk you may run into too many files issue if f2 has large number of lines. Change the loop content to {line=$0; sub(s, q k q, line); f=k".inc"; print line >> f; close(f)}. This assumes .inc files don't already exist, otherwise, you'll get content appended.

Sundeep
  • 23,246
  • 2
  • 28
  • 103