7

Say I had a config file /etc/emails.conf

email1 = user@dinkum.dorg 
email2 = user@winkum.worg
email3 = user@stinkum.storg

and I wanted to get email2

I could do a:

grep email2 /etc/emails.conf | cut -d'=' -f2 

to get the email2, but how do I do it "cooler" with one sed or awk command and remove the whitespace that the cut command would leave?

Peter Turner
  • 1,654
  • You can remove the first cat: grep email2 /etc/emails.conf | ... – Carlos Campderrós May 04 '15 at 15:59
  • @CarlosCampderrós dang, I had thought I tried that but it failed for some completely unknown hidden reason (because obviously it should have worked). I just put the file name at the end of the cut wrongly and that's why it didn't work. I revised the question, I don't think it invalidates the answers. – Peter Turner May 04 '15 at 16:20
  • I really don't understand your question: you already have the string that you're searching for: result="email2" -- what are you really trying to do? – glenn jackman May 05 '15 at 01:25

5 Answers5

5

How about using awk?

awk -F = '/email2/ { print $2}' /etc/emails.conf
  • -F = Fields are separated by '='

  • '/email2/ { print $2}' On lines that match "email2", print the second field

wjandrea
  • 658
Carlos Campderrós
  • 2,111
  • 2
  • 16
  • 18
4

The exact equivalent would be something like:

sed -n '/email2/{s/^[^=]*=\([^=]*\).*/\1/;p;}' < file

But you'd probably want instead:

sed -n 's/^[^=]*email2[^=]*=[[:blank:]]*//p' < file

(that is match email2 only on the part before the first = and return everything on the right of the first = (skipping leading blanks), not only the part up to the second = if any).

2
perl -nlE 's/email2\s*=\s*// and say'    file

Where:

  • perl -nl is a for each line do...
  • s/email2 = // removes the searched email id and if you could do it ...
  • say prints the current input input line
  • \s* zero or more spaces (equivalent to [ \t\n]*)
JJoao
  • 12,170
  • 1
  • 23
  • 45
  • I'll give you a +1 for golfing, but where I'm running this (some sort of stripped down Cisco appliance), I'm not sure I'm going to have perl, especially the version of perl that has say. – Peter Turner May 04 '15 at 17:51
  • perl 5.10 appeared 7 year ago but sometimes we don't have it... perl -nle 's/email2\s*=\s*// and print' – JJoao May 04 '15 at 17:59
2

To get something like grep | cut you can use sed -n s/A/B/p.

By default, sed prints every line after all commands are processed. You can silence all output that you don't explicitly print from a command with sed -n.

The s command takes the form s/$FIND/$REPLACE/$FLAGS. Specifically, the p flag prints the line whenever a replacement is made.

With these combined, you can easily match and cut:

sed -nE "s/email2 = (.+)/\1/p" < /etc/emails.conf

In fact, this is strictly more powerful than grep | cut because you can use an arbitrary replacement pattern.

(The -E option enables modern regex, which allows you to reference capture groups in the replacement pattern. For a simple cut, you can get away without it by using more clever patterns.)

cbarrick
  • 121
  • 2
0

There is no need to set the field separator to any special value such as "=". By default, AWK uses contiguous spaces and tabs as field separators, which are skipped, so it will interpret each line of your file as having three fields, without any leading space on field three

awk '/^email2/ { print $3 }'

produces

user@winkum.worg

The above would also match any lines starting with email2, such as email20, for exact match you can use

awk '$1 == "email2" { print $3 }'