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 ().

NN*ST*XYZ Test Corporation*9*122334455… 
NU*987 ELS.… 
N3*123 Highway Street… 

My expected output is:

  • 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 '14 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 '14 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 '14 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 '14 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 '14 at 0:32

There are many ways to do this. For example:

  • grep

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


    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


    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


    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


    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


    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
  • 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 '14 at 1:57

Using awk:

awk -F\* '/^BIG/ {gsub(/…/,""); print $NF}' file
  • 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 '14 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 '14 at 1:56

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.