3

I have data such as

ID | Name | Grade
1|Robin Hood so hood | A
2|Gwen Stack DO Rick Stacy |C
3|Bling s/o Peter| A

where so is son of, DO is daughter of, S/O is son of.

I am gazed How I can arrive to

     ID | Name | Grade
    1|Robin Hood| A
    2|Gwen Stack  |C
    3|Bling| A

As at end I will be mailing these guys there grades where I am not willing to feed full string just Name

I was trying to use while loop, with awk which gives 2nd field into array then for loop to array which was uncessfull

Any SED or AWK method ??

4
  • 1
    If you just want ot remove so, DO, s/o you can do sed -r 's/ (so|DO|s\/o) / /'. If that's not what you want, please clarify your question Commented Nov 19, 2015 at 17:43
  • updated the question, I want string before so|DO|s\o Commented Nov 19, 2015 at 18:10
  • In the case where ID = 3, you have "Bling Peter", which are strings both before and after s/o. Do you really just want to have "Bling" there? Commented Nov 19, 2015 at 18:20
  • yes Only Bling as that what is needed Commented Nov 19, 2015 at 18:21

4 Answers 4

4

You can use this sed command:

sed -i.bak 's~ [sSdD]/*[oO] [^|]*~~' file
ID | Name | Grade
1|Robin Hood|A
2|Gwen Stack|C
3|Bling|A

Or using awk:

awk -F ' [sSdD]/?[oO] [^|]*' '{print $1 $2}' file
ID | Name | Grade
1|Robin Hood|A
2|Gwen Stack|C
3|Bling|A
Sign up to request clarification or add additional context in comments.

7 Comments

I haven't understood [^|]*~~' this part of sed
[^|]* matches 0 or more characters before a pipe
I never used ~~ in regex expression [used only as condition but not expression. what is ~~
~ is just an alternate sed delimiter. We could also use: 's# [sSdD]/*[oO] [^|]*##'
+1 Upvote: I just realized few days ago if we accept answer in just few minutes others may not get time to comeup with there solution. So I am waiting for other potential ways of solving it
|
0

sed

sed -r 's/(so|DO|S[/]O)[^|]+([|])/\2/g

Comments

0
awk '{sub(/s\/o Peter/,"")}{sub(/d \| A/,"\ |A")}NR>1{print $1,$2, $NF}NR==1' file
ID | Name | Grade
1|Robin Hood |A
2|Gwen Stack |C
3|Bling | A

Comments

0

This answer should feel straightforward as it is using | as the field separator, and the sub is only working on the second field. It is also making sure that so, DO, and s/o are separate from names by making the regex in the sub take into account spaces on either side of the three:

awk 'BEGIN {OFS=FS="|"} sub(/ (s\/?o|DO) .*/, "", $2) + 1' file
ID | Name | Grade
1|Robin Hood| A
2|Gwen Stack|C
3|Bling| A

One other thing -- it looks like from the middle part of your question you may be wanting case insensitivity. If you have gawk, you can use IGNORECASE. Otherwise, here is the edited regex.

awk 'BEGIN {OFS=FS="|"} sub(/ ([Ss]\/?|[Dd])[Oo] .*/, "", $2) + 1' file

Here is the one if you want to accept case insensitive D/O as well.

awk 'BEGIN {OFS=FS="|"} sub(/ [SsDd]\/?[Oo] .*/, "", $2) + 1' file

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.