Home > Enterprise >  How to iterate over two files and find all occurrences in file1 matching file2, line by line, then r
How to iterate over two files and find all occurrences in file1 matching file2, line by line, then r

Time:07-15

I have a file I am trying to initiate a global find and replace pattern. I want to find all occurrences of file2, line by line, within file1, then replace these occurrences with file3 which match the pattern of file2.

This is the file I am trying to chage.

file1.txt:
  34   │ ![[Pasted image 20220506211935.png]]
  35   │ 
  36   │ ![[Pasted image 20220506212047.png]]
  37   │ 
  38   │ ![[Pasted image 20220506212121.png]]
  39   │ 
  40   │ ![[Pasted image 20220506213028.png]]

I would like to search file1 with each pattern in this file line by line.

file2.txt:
   1   │ 20220506211935.png
   2   │ 20220506212047.png
   3   │ 20220506212121.png
   4   │ 20220506213028.png

Each search pattern from file2 would then be replaced with the content from file3.

file3.txt:
   1   │ ![image](https://m0d1cumc0rvu5.github.io/docs/assets/images/20220506211935.png)
   2   │ ![image](https://m0d1cumc0rvu5.github.io/docs/assets/images/20220506212047.png)
   3   │ ![image](https://m0d1cumc0rvu5.github.io/docs/assets/images/20220506212121.png)
   4   │ ![image](https://m0d1cumc0rvu5.github.io/docs/assets/images/20220506213028.png)

I have failed with vim:

%s#![[Pasted image #![image](https://m0d1cumc0rvu5.github.io/docs/assets/images/#g
%s#]]#)#g

This does not work in the .md file I am targeting. (file1.txt in example)

Similarly, using sed directly on the file with the current syntax does not work.

sed -r 's#[[Pasted image #![image](https://m0d1cumc0rvu5.github.io/docs/assets/images/#g' file1.txt

This is why I created the additional files to ideally loop over them such as:

sed -i 's/`cat file2.txt`/`cat file3.txt/g' file1.txt

I have seen similar questions, yet none have adequately answered what I am trying to achieve.

Desired result:

file1.txt
  34   │ ![image](https://m0d1cumc0rvu5.github.io/docs/assets/images/20220506211935.png)
  35   │ 
  36   │ ![image](https://m0d1cumc0rvu5.github.io/docs/assets/images/20220506212047.png)
  37   │ 
  38   │ ![image](https://m0d1cumc0rvu5.github.io/docs/assets/images/20220506212121.png)
  39   │ 
  40   │ ![image](https://m0d1cumc0rvu5.github.io/docs/assets/images/20220506213028.png)

CodePudding user response:

awk '
    # keep track of which file is being processed
    FNR==1 { file   }

    # store search and replacement text
    file==1 { search[  i] = $0; next }
    file==2 { replace[  j] = $0; next }

    # sanity check
    file==3 && FNR==1 {
        if (i!=j) {
            print "search/replace mismatch" >"/dev/stderr"
            exit 1
        }
    }

    # look for lines to replace
    file==3 {
        for (k=1; k<=i; k  ) {
            if (index($0,search[k])) {
                # found: print replacement and skip to next line
                print replace[k]
                next
            }
        }
        # no match: print original line
        print
   }
' file2.txt file3.txt file1.txt > new-file1.txt
  • Related