1

I am having difficulties parsing my data. In the file shown below, I want to get the characters after BIG**20021208*00001**. I tried sed '/BIG.20021208.00001\**/!d;s///;s/\*.*//' but it doesn't work. I think the problem has to do with the line separator ().

BIG*20021208*00001**A1001… 
TO*7284*0001…BIG*20021208*00001**A999… 
NN*ST*XYZ Test Corporation*9*122334455… 
NU*987 ELS.… 
N4**NY*98765… 
ITD*01*3*2**30**45*****60… 
N3*123 Highway Street… 
N4**12345… 
ITD*001*3*2**30**30*****60… 
BIG*20021208*00001**8263-83313… 
ITD*001*3*2**30**30*****60… 
BIG*20021208*00001**8263-83313… 

My expected output is:

A1001
8263-83313
8263-83313
7
  • 1
    Please edit your question and clarify. We need to see your expected output. The last line has BG instead of BIG is that a typo?
    – terdon
    Jul 8, 2014 at 0:34
  • Apologies, that's BIG and not BG. The code works, it can parse but the rest of the values next to BIG.20021208.00001 were also parse and not A1000 and A1001 specifically.
    – user74775
    Jul 8, 2014 at 1:52
  • Well, my answer should do what you want regardless. Does it? If not, please show us your expected output.
    – terdon
    Jul 8, 2014 at 10:12
  • @terdon, please ignore my previous question. Actually, I tried this one - grep -oP 'B.?G.20021208.00001..\K\w+', it works however when a file has a value containing - (e.g 8263-83313), the one that will be parse is only those values preceding to - (e.g. 8263) and not the whole value (which is suppose to be this 8263-83313). Any idea?
    – user74775
    Jul 8, 2014 at 23:51
  • Please edit your question and show your exact input and your expected output. Include all examples you need to be able to deal with and clearly show the output you want.
    – terdon
    Jul 9, 2014 at 0:32

2 Answers 2

4

There are many ways to do this. For example:

  • grep

    grep -oP 'BIG\*20021208\*00001\**\K[A-Z0-9-]+' file
    

    Explanation

    The -o makes grep print only the matched portion of a line and the -P activates Perl Compatible Regular Expression (PCRE) syntax. The \K in PCREs causes whatever was matched up to that point to be discarded (and therefore not printed, because of -o). [A-Z0-9-] is a character class that matches any capital letter from A to Z, any number or - and which can be repeated one or more times (+).

    If your target strings can contain lower case letters as well, just run grep with the -i flag or change the character class to [a-zA-Z0-9-].

                                                              --- or ---

    grep -oP 'BIG\*20021208\*00001\**\K.+(?=…)' file
    

    Explanation

    This is just like the above only here, there's a positive lookahead ((?=…)) which means that .+ will only match if preceding a .

  • sed

    sed -rn 's/…//g;s/.*BIG\*20021208\*00001\**//p;' file
    

    Explanation

    The s/from/to/ is sed's substitution operator. It replaces from with to. The First one replaces with nothing, it deletes them (the g ensures this is done for all matches on the line). The second deletes everything from the beginning of the line (.*) up to BIG*20021208*00001 (* has a special meaning in regular expressions so it needs to be escaped with \*), then 0 or more asterisks (\**). Combined, they delete everything except what you want.

    The -n suppresses printing of any output. The p at the end of the 2nd substitution operator causes sed to print any lies that where that substitution was successful.

  • awk

    awk -F'[*…]' '/BIG\*20021208\*00001\**/{print $(NF-1)}' file
    

    Explanation

    The -F set's awk's input field separator to either * or . This means that the penultimate field will be the one you want. The command above prints it on lines that match BIG*20021208*00001*.

  • Perl

    perl -lne '/BIG\*20021208\*00001\**(.*)…/ && print "$1"' file
    

    Explanation

    The -n makes perl read its input line by line and apply the script given by -e to it. The -l adds a newline character to each print call. The command above will attempt to match the string of interest (see the explanation to the sed example above) and print it if successful.

    You could also use the same approach as in the awk example:

    perl -F'[*…]' -lane '/BIG\*20021208\*00001\**/ && print "$F[$#F]"' file
    
1
  • Apologies, that's BIG and not BG. The code works, it can parse but the rest of the values next to BIG.20021208.00001 were also parse and not A1000 and A1001 specifically.
    – user74775
    Jul 8, 2014 at 1:57
2

Using awk:

awk -F\* '/^BIG/ {gsub(/…/,""); print $NF}' file
A1001
8263-83313
8263-83313
2
  • Another question is, how about when BIG*20021208*00001A1001 has another additional value let’s say BIG*20021208*00001A1001**20140303*121 and another is what if the segment delimiters were not * at all and the line delimiters are not … also but again I still want to get the same data which are A1001, 8263-83313, 8263-83313.
    – user74775
    Jul 9, 2014 at 1:54
  • 2
    @user74775 Well, at some point you have to make up your mind what the actual values and delimiters are, because if you keep expanding/changing the scop of your question you are just wasting people's time...
    – jasonwryan
    Jul 9, 2014 at 1:56

You must log in to answer this question.

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