1

I have a file that contains, among other characters, many hundreds of email addresses. The email address is always between the characters "=>" and "<=". So

=>[email protected]<=

In the text file it looks like this:

323168fdsafdafsdfj=>[email protected]<=askdjfköj4243j40278012
jköjökajsdöfajsdkf2323323j=>[email protected]<=jököj

How can I use text processing to exclude the email address and write it to a new file?

6
  • Try: grep -oP '(?<=\=>)[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(?=<=)' file.txt > new_file.txt
    – kyodake
    Nov 27, 2023 at 12:46
  • I had edited my question. Sorry, there were two mistakes.
    – D-T
    Nov 27, 2023 at 12:57
  • Unfortunately that does not work. But still thanks for the help. ​
    – D-T
    Nov 27, 2023 at 13:07
  • 2
    Are there multiple occurrences of the pattern =>...<= in each single line or only one per line?
    – Raffa
    Nov 27, 2023 at 14:03
  • You ask about "excluding" but I wonder if you mean "extracting". Do you want the text without the email addresses in the new file (excluding) or the email addresses without the other text (extracting)?
    – tripleee
    Nov 28, 2023 at 8:00

3 Answers 3

3

If there are multiple addresses per line, as shown in your example, then I'd suggest using perl - since its regex engine allows non-greedy matches:

perl -pe 's/=>.*?<=//g' < file > newfile

You could try to synthesize non-greedy matching in sed e.g.

sed 's/=>[^=]*<=//g' < file > newfile

however this will fail if any of the email addresses contains the = character (not sure if the RFC permits that).

With awk, you could make the input field separator a regex that matches and consumes the addresses (this has the same issue with = in an address as the sed solution, for the same reason):

awk -F '=>[^=]*<=' '{$1=$1} 1' < file > newfile 
1

With awk:

awk 'gsub("=>.+<=", "", $0)' file > newfile

… that wold delete the first occurrence of => and anything after it (has to be at least one character) up to the last occurrence of <= including it in every line. Which might result in deleting portions in between multiple occurrences of =>...<= if it happened more than once in the same line … In which case you can change "=>.+<=" to "=>[^=]+<=" which will match any character but the character = in between each leading => and the following <= and that should match and delete each single =>...<= pattern individually given there are no = characters in between and that’s AFAIK as close as it gets to resemble none-greedy RegEx matching in awk regarding your requirement which by the way is not clear as which of the two cases it is.

0

Use this

grep -Pio '\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b' orig_file.txt > only_mails_in_file.txt  
1
  • 1
    I think OP wants to exclude emails, but this includes emails only and excludes everything else ... Regardless, I think it can be simplified to grep -Po '(?<=>).*?(?=<=)'
    – Raffa
    Nov 27, 2023 at 17:59

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .