6

I have a file where each line contains a sentence where one word is found between the character > and <. For example:

Martin went shopping at >Wallmart< and lost his wallet
French food >tastes< great

I am looking for a command to run from the shell that will print the word inside ">" and "<" for every line.

Thanks in advance.

  • 4
    Is there only 1 of those words per line? and can there be any occurence of a > or a < elsewhere than around that 1 occurence ? – Olivier Dulac Jul 9 at 12:22
  • Is Wallmart a better-constructed version of Walmart, perhaps? ;-) – Toby Speight Jul 9 at 15:34
  • @OlivierDulac no, it occurs more than once, my example was over simplified, and I was also wondering what happens if I want the word between, say, "food >" and "< great" – ZakS Jul 9 at 18:52
9

For awk:

awk -F '[><]' '{print $2}' file

That sets the field separator as either > or < and prints the second field which is what is between those two characters.

For sed:

sed 's|.*>\(.*\)<.*|\1|' file

That uses the () to print what is between the > and anything coming after it and the < and anything coming before it.

The output

Wallmart
tastes
  • Thanks for the explanation! – ZakS Jul 9 at 6:34
  • 3
    to be completely honest, the awk solution : would also match : <something< or >anotherthing> ... and if a line contains, say, >> this is >important<, it would yeld "" (as it is the empty field between the first 2 >). and your sed : will matche the longuest occurence of <something with maybe > and < in it .. > in a line. You could use a (little bit) better version : sed -e 's#.*>\([^><]*\)<.*#\1#' (will replace the line with the first occurence of <something>) – Olivier Dulac Jul 9 at 12:17
  • OlivierDulac That's true but the questioner has indicated that that's isn't the case. If it were then I'd keep the sed solution and use Perl instead of awk. – Nasir Riley Jul 9 at 13:47
  • @OlivierDulac in your example, wouldn't it create 3 fields, one empty, one " this is " between the 2nd and 3rd >'s, and then finally a third field "important"? – ZakS Jul 9 at 18:56
  • 1
    @ZakS the answer's awk would create 5 fields, not 3. Each occurrence of the separator (which for the awk is set at "exactly 1 > or 1 <") separating a field, it would also have a first empty field (before the first >) and a 5th empty one after the last <. – Olivier Dulac Jul 10 at 8:01
11

What about grep?

grep -oP "(?<=\>).*(?=<)"  file

Output:

Wallmart
tastes

EDIT:

Following @Toby Speight comment, and assuming that between > and < there are only words, to avoid matching > and < in other contexts the command should be

grep -oP "(?<=\>)\w+(?=<)"  file
  • 1
    Replace the .* with \w+ if < and > may occur in other contexts, and we want only the matches where they delimit single words. – Toby Speight Jul 9 at 15:32
  • Could you provide an explanation for the code? – user1993 Jul 9 at 23:35
  • 1
    @user1993 -o option retrieves only the match, not the line (default behaviour of grep).-P option allows to perform perl like regular expressions. (?<=\>)content(?=<) captures the pattern >content<, content being another regular expression, which is what is being returned. – guillermo chamorro Jul 10 at 15:04
0

I tried with below command and it worked fine

awk -F ">" '{print $2}' filename| sed  "s/<.*//g"

output

Wallmart
tastes

python

#!/usr/bin/python
o=open('filename','r')
for i in o:
    k=i.split('>')[1].split('<')[0].strip()
    print k

output

Wallmart
tastes

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.