15

I want to read one part of one line from a file. For example:

POP3_SERVER_NAME = localhost

I want to return only localhost, using sed.

This text is on the third line. I do this to extract the line:

sed -n '3p' installation.sh

How do I extract only the localhost part?

23

awk might be a better tool here.

$ cat test.dat
LINE 1
LINE 2
POP3_SERVER_NAME = localhost

Search for lines that contain "POP3_SERVER_NAME"; print the last field. This doesn't depend on POP3_SERVER_NAME always being on line 3, which is probably a Good Thing.

$ awk '/POP3_SERVER_NAME/{print $NF}' test.dat
localhost

Depending on your application, you might need to make the regular expression more stringent. For example, you might want to match only that line that starts with POP3_SERVER_NAME.

$ awk '/^POP3_SERVER_NAME/{print $NF}' test.dat
localhost

Using sed is a little less intuitive. (Thanks, I'm aware of the irony.) Address the line that contains POP3_SERVER_NAME anywhere. Substitute an empty string for all the text from the beginning of the line to the optional space following "=". Then print.

sed -n -e '/POP3_SERVER_NAME/ s/.*\= *//p' test.dat
  • 2
    The awk command is nice - but only if you've got spaces around the =. It won't work for POP3_SERVER_NAME=localhost. – Marcel Stör Feb 14 '16 at 11:07
  • 2
    @Marcel, You can change the delimiter used by awk from spaces to something else using -F. For instance: -F "=" will use = as a delimiter in the case you mention. – mattpr Apr 11 '18 at 7:44
7

Replace the p command by a substitution that removes the unwanted part of the line.

sed -n '3 s/^[^=]*= *//p' installation.sh

You may want to match the line by keyword rather than by position.

sed -n 's/^ *POP3_SERVER_NAME *= *//p' installation.sh
5
echo "POP3_SERVER_NAME = localhost" | sed 's/.*= //'
localhost

Or if you have the contents in a file:

sed 's/.*= //' somefile.txt
localhost
  • ok, but i read in my file like this: sed -n '3p' installation.sh – Mercer Jul 30 '13 at 15:21
  • 2
    @Mercer - see the updates I added to the answer. – slm Jul 30 '13 at 15:25
  • @Adam Siemion - thank you, but how to indicate the line number? – Mercer Jul 30 '13 at 15:27
4

Looks like you've got a config file. What you could do is similar to what Adam Siemeon/slm suggest:

sed -nr 's/[^=]+=\s*(.+)$/\1/p' filename

where [^=] excludes all '=' characters, + says one or more of the same type of character, this followed by an actual =, \s any whitespace (including tabs \t and new lines \n, \r\n, and plain spaces ' ', whereas * means zero or more of the same type, parentheses catch what's inside to place the matched character sequences into the \1, \2, ..., \n replacement placeholders, $ means the end of a line. This follows the typical replacement pattern of: s/.../.../modifiers. The command line option -r stands for extended regex syntax (as a matter of convenience) and -n means output nothing until or unless explcitly requested. The p modifier prints out the result.

You could make a global search with the g modifier like:

sed -nr 's/[^=]+=\s*(.+)$/\1 /pg' filename  # note the space after \1

so that you get a string separated by ' ' (could be \n, \t, or what have you) which you can process easily.

Both is valid provided your values preceded by the equation character span up to the end of a line and are not followed by comments or other characters with semantics deviating from a simple "value".


Edit:

I can't comment here yet on other's posts. To indicate the line just pass the line number, in your case 3, before s or before the initiating quote char (just like in vim).

sed -nr '3s/[^=]+=\s*(.+)$/\1/p' filename

Please take a look at info sed. For example, 3.2 and 4.7 are of particular interest to you.

4

You can use the cut command, setting the delimeter to '=' and then print the second field like this:

cut -d'=' -f2
3

Multiple ways to do it, considering your file is called foobar:

Specify the pattern to search for:

PAT=POP3_SERVER_NAME

Extract using sed

sed -n "/$PAT/p" foobar | sed "s/$PAT = //"

Or using sed and cut

sed -n "/$PAT/p" foobar | cut -d' ' -f3
2

The beauty of Linux/Unix is that there is usually more than one way to accomplish something. In the op's case, there are at least four different ways to extract the POP server name from the file:

  1. grep POP3_SERVER_NAME installation.sh | cut -d'=' -f2
  2. grep POP3_SERVER_NAME installation.sh | awk '{print $3}'
  3. grep POP3_SERVER_NAME installation.sh | sed 's/.*= //'
  4. sed -n 's/^.*POP3_SERVER_NAME = //p' installation.sh

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.