I need to extract similar patterns from data below. The pattern starts with '.' or '' then to the keyword I want, then followed by ''. We can assume the format is

  1. LSUFE-numbers_
  2. PCRF-numbers_

Sample data

/home/mobaxterm/Data/FW/FW3/FW.3.1/releases/patch_PCRF-17717B1.jar,patch_PCRF-17717B1.jar,yschew,2015-10-21 11:31:58.000000000,patch
/home/mobaxterm/Data/FW/FW9/CW.1/releases/D/patch_FW_9.3.1.LSUFE-583B1_i86pc.jar,patch_FW_9.3.1.LSUFE-583B1_i86pc.jar,yschew,2015-10-21 11:31:58.000000000,patch,i86pc

Desired output


I have tried using answer from https://stackoverflow.com/questions/8777901/extract-specific-words-from-a-line

sed -r 's/.*LSUFE-(\S+).*/\1/'

but it didn't work, all I got is a blank screen. Right now what I am thinking is doing something similar like this

sed -e 's/LSUFE-*/,/\_/' output.txt

but of course, I didn't get it to work, my idea is doing it 1 by 1 for each pattern, read from the matching pattern until it encounters an underscore.

  • 1
    Your output data does not exist in your input data (PCRF-17717B1)... – jasonwryan Oct 23 '15 at 2:53
  • I updated the question – Xeon Oct 23 '15 at 2:59

You could use something like this:

$ grep -oE '(LSUFE|PCRF)-[^._]*' input.txt  | uniq

The uniq is required because each line contains both the full path to the patch filename and the basename (i.e. without the path).

Alternatively, if the order of the output doesn't matter, you could use sort -u rather than uniq - this will also eliminate any duplicates that occur on multiple lines of the input.

Here's another alternative in perl:

perl -F, -a -e 'next unless $F[1] =~ s/.*((LSUFE|PCRF)-[^._]*).*/$1/  ; print $F[1],"\n"' input.txt

This performs the regexp search and replace only on field 2 ($F[1] in perl as perl arrays are zero-based), and then prints field 2.

This perl version appends the matching text as an extra field to the end of the input line:

perl -F, -a -e 'chomp ; next unless $F[1] =~ s/.*((LSUFE|PCRF)-[^._]*).*/$1/ ; print $_,",",$F[1],"\n"' input.txt 

It uses chomp() to strip the trailing \n from the input line, then prints the input line ($_), a comma, the modified field 2, and a newline.

  • It worked, thanks! I see what I am missing now. Thanks again. What if I want to append the word to the end of the line where it matches? – Xeon Oct 23 '15 at 3:16
  • Based on your edit, is there no way to do this using grep? – Xeon Oct 23 '15 at 3:38
  • the perl version wasn't a response to your extra question, it was just another way of performing the original task, i hadn't even seen your comment when i wrote it. BTW i have no idea what you mean by "What if I want to append the word to the end of the line where it matches?" Whatever that means, I doubt if grep can do it because grep is only good for finding patterns, not for appending stuff to lines. With the perl version, you can append whatever you like to the line just by adding it to the print statement. – cas Oct 23 '15 at 3:41
  • Oh, what I meant was take the output of grep PCRF-17717B1 and append it to the end of the line where the pattern matches, like the output below /home/mobaxterm/Data/FW/FW3/FW.3.1/releases/patch_PCRF-17717B1.jar,patch_PCRF-17717B1.jar,yschew,2015-10-21 11:31:58.000000000,patch,PCRF-17717B1 – Xeon Oct 23 '15 at 3:46
  • @xeon, answer updated with append version of perl one-liner – cas Oct 23 '15 at 3:51

Only the catched info

sed  's/.*\(LSUFE-\([^_.]*\)[_.].*/\1/' YourFile

catched added to the end with , as separator

sed  's/.*\(LSUFE-\([^_.]*\)[_.].*/&,\1/' YourFile

With several pattern at once

sed  -e 's/.*\(LSUFE-\([^_.]*\)[_.].*/\1/' -e 's/.*\(PCRF-\([^_.]*\)[_.].*/\1/' YourFile

with GNU sed

sed 's/.*\(\(LSUFE\|PCRD\)-\([^_.]*\)[_.].*/\1/'

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.