0

I have a problem with a grep.

I have a file called Uniprot_interactors.txt containing a list of codes (ex. GRT986E) and sometimes between objects there are one or more empty lines.

In some other cases I have an object consisting of 2 parts divided by a low dash (ex. TRY546 _ TRE578) and these lines must be considered as if they were empty.

After that I have another file Good_interactors.txt containing a list of codes and for everyone a variable (es. aaaaaa) is associated. I would like to get an output (output.txt) from the grep of these files but I want to keep the lines empty as in the first file.

An example:

  • file1: UNIPROT_interactors.txt

    QR846OI
    
    PO3R56
    UJ6Y68
    
    
    YU654R
    
    PL92WS
    GH654Y _ HUY765R
    PIHYUD
    
  • file 2: GOOD_Interactors.txt

    TYRT68Y aaaaaaaaa
    QR846OI bbbbbbbbb
    FDR59I cccccccc
    PO3R56 ddddddd
    UJ6Y68 eeeeeee
    VFR6y7 fffffff
    PIHYUD gggggggg
    UH7609 hhhhhhhh
    
  • file output.txt (same format of file 1)

    QR846OI bbbbbbbbb
    
    PO3R56  ddddddd
    UJ6Y68 eeeeeee
    
    
    YU654R
    
    PL92WS
    GH654Y _ HUY765R
    PIHYUD gggggggg
    

I tried to use this code:

grep -f Uniprot_interactors.txt GOOD_interactors.txt > output.txt

but the format of file 1 is not preserved and empty lines have been deleted.

1

You can't use grep here as the purpose of grep is to extract lines (or in some cases, words) matching a particular regular expression. The grep utility does not modify data, which is what you want to do (add data to lines from one file to another).


Using awk to save the good interactors in an associative array, names, with the Uniprot identifier as the key. Then outputting these interactors depending on the Uniprot identifier in the first column (while passing on lines with more than one column or with no known good interactor unchanged):

$ awk 'FNR==NR { names[$1] = $0; next } NF > 1 || !($1 in names) { print; next } { print names[$1] }' GOOD_Interactors.txt UNIPROT_interactors.txt
QR846OI bbbbbbbbb

PO3R56 ddddddd
UJ6Y68 eeeeeee


YU654R

PL92WS
GH654Y _ HUY765R
PIHYUD gggggggg

Note that we give both files as input to the awk command. While reading from the first file, only the block with the FNR==NR condition will be triggered, while this block would be skipped while reading from the second file.

The special variables FNR, NR and NF are the number of records (lines) read from the current file, the number of records read over all, and the number of fields (columns) in the current record, respectively.

2
  • The command works well, only some variables are formed by a string of several words and with this command I can only grep the first word. How can I modify this thing? An example of a variable: "aaaaa rty ity2" and in this case it is taken only "aaaaa"
    – Tommaso
    Jun 17 '20 at 7:37
  • @Tommaso See updated answer.
    – Kusalananda
    Jun 17 '20 at 8:09
0

loop over file1 reading line if empty echo it else grep corresponding data and print it

while read line ; do
    if ((${#line}));then
        grep "${line}" file2
    else
        echo
    fi
done < file1 > output.txt

or

file2content="$(cat file2)";
while read line ; do
    if ((${#line}));then
        grep "${line}" <<< "${file2content}"
    else
        echo
    fi
done < file1 > output.txt

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.