20

I want to print a part of a line in a file. The whole line looks like this.

Path=fy2tbaj8.default-1404984419419

I want to print only the characters after Path=. I have tried grep Path filename | head -5. But its not working.It still shows the entire line. How can i do this?

0

6 Answers 6

43

You can use grep and just grep:

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

enter image description here

Explanation:

From man grep:

   -o, --only-matching
          Print only the matched (non-empty) parts of a matching line,
          with each such part on a separate output line.
   -P, --perl-regexp
          Interpret PATTERN as a Perl compatible regular expression (PCRE)

The lookbehind (?<=Path=) asserts that at the current position in the string, what precedes is the characters Path=. If the assertion succeeds, the engine matches the resolution pattern.

For Perl 5 regular expression syntax, read the Perl regular expressions man page.

2
  • This helped. For me, what was best was grep -orn . -e 'myQuery' (to search the current directory recursively for a string and show the line number where matches were found).
    – Ryan
    Mar 13, 2020 at 14:41
  • Actually grep -orn ".\{0,10\}myQuery.\{0,10\}" . was even better because it shows context around the matches. superuser.com/a/1005747/74576
    – Ryan
    Mar 13, 2020 at 14:49
15

you can use cut command for this purpose.

grep Path filename |cut -c6-

Here -c6- option means print from 6th to last character.

8

The awk solution is what I would use, but a slightly smaller process to launch is sed and it can produce the same results, but by substituting the PATH= part of the line with "" , i.e.

  sed -n 's/^Path=//p' file

The -n overrides seds default behavior of 'print all lines' (so -n = no print), and to print a line, we add the p character after the substition. Only lines where the substitution happens will be printed.

This gives you the behavior you have asked for, of greping for a string, but removing the Path= part of the line.

If, per David Foerster's comments, you have a large file and wish to stop processing as soon as you have matched and printed the first match to 'Path=', you can tell sed to quit, with the q command. Note that you need to make it a command-group by surrounding both in { ..} and separating each command with a ;. So the enhanced command is

sed -n 's/^Path=//{p;q;}` file

IHTH

2
  • Make that s/^Path=//p since we only want to match at the beginning of a line. We can match only the first occurrence with s/^Path=//{p;q}. Sep 29, 2014 at 16:13
  • @DavidFoerster : Thanks, for those improvements, I'm adding them to my answer.
    – shellter
    Sep 29, 2014 at 17:21
6

With GNU grep:

$ echo Path=fy2tbaj8.default-1404984419419 | grep -oP '(Path=)\K.*'
fy2tbaj8.default-1404984419419

\K keeps the stuff left of the \K, don't include it in $&.

4
  • It would be better if you include this one '(Path=)\K.*' according to the OP is supposed. I also was looking this command. \K is nice option. thanks. upvoted Sep 30, 2014 at 8:23
  • @KasiyA: Updated. Feel free to edit anything you think make the answer better.
    – cuonglm
    Sep 30, 2014 at 8:27
  • @KasiyA why the parentheses? They don't do anything useful there, this does the same thing: grep -oP 'Path=\K.*'
    – terdon
    Sep 30, 2014 at 23:51
  • 1
    @terdon: As I guess, he want to emphasis the part that OP don't want.
    – cuonglm
    Oct 1, 2014 at 1:25
5

grep greps a line of text and displays it. head displays the first n lines of text, not characters.

You're looking for sed or awk:

awk '{print $2}' FS='='

This sets = as a field separator and prints the second field.

3
  • Is it not even better to use FS='PATH='?
    – don.joey
    Sep 29, 2014 at 14:55
  • 1
    You can do awk as a "one liner" awk 'BEGIN { FS = "=" } ; /pattern/ {print $2}' file_to_search
    – Panther
    Sep 29, 2014 at 14:56
  • @don.joey: I'd use FS='=' so you can use the $1 ("PATH") when needed.
    – Jan
    Sep 29, 2014 at 15:04
1

Of course the solution is to use grep -Po.

Let's add some other solutions, for completeness:

  • with cut, setting the delimiter the =:

    cut -d'=' -f2 file
    
  • It might be a bit risky, but you can also source the file, so that $Path will contain the value.

    source file
    echo "$Path"
    

Test

$ cat a
this=aaabbccc
that=dddeee
$ source a
$ echo "$this"
aaabbccc
$ echo "$that"
dddeee

As per comments, see how to source just part of the file:

$ cat a
Path=22
Path=33
$ source a
$ echo $Path
33
$ source <(head -1 a)
$ echo $Path
22
13
  • 1
    If file contains more lines that starts with Path= then what is your solution? it just return last one of them. Sep 29, 2014 at 15:31
  • That's out of the scope of the question, as the OP is supposed to know where in the file are these lines. However, you can play around with source and head/tail. For example, source <(head -3 file) to just get the 3 first lines of the file, etc.
    – fedorqui
    Sep 29, 2014 at 15:34
  • Still returns last one Sep 29, 2014 at 15:40
  • @KasiyA of course it returns the last one, that's why I suggest using head/tail to get the block of code in which it is unique.
    – fedorqui
    Sep 29, 2014 at 15:42
  • I said still returns last one also with using head/tail Sep 29, 2014 at 15:44

Not the answer you're looking for? Browse other questions tagged .