0

I have a log file like bellow.

130023432 195047 /media/ismail/SSDWorking/book-collection/_Books/book 1.epub
130023433 195047 /media/ismail/SSDWorking/book-collection/_Books/book 2.epub
130023431 195047 /media/ismail/SSDWorking/book-collection/_Books/book 3.epub

I have a variable, var=130023432

I want to say if first word equals to $var, then print all except the first two words.

So, in this case the output will be:

/media/ismail/SSDWorking/book-collection/_Books/book 2.epub

What I have tried so far is grep -oP "(?<=$var \d+ ).*$'" but it gives error grep: lookbehind assertion is not fixed length

How can I achieve that?

7
  • grep -oP "$var \d+ \K.*" works. Commented May 10, 2023 at 16:23
  • awk -v var="$var" '$1 == var {print}' | cut -d" " -f3 also works. Commented May 10, 2023 at 16:25
  • 2
    If you change {print} to {$1=$2=""; print $0} then you will not need to pipe to cut and it will work with any type or amount of whitespace. Also, if you have an answer that works you can post it as an answer then accept it in a day or two. Makes the question/answer easier to search for.
    – doneal24
    Commented May 10, 2023 at 16:40
  • @doneal24 I think there is a space behind /media/..... How can I remove that? Commented May 10, 2023 at 16:48
  • Is the space present in your input file? I did a cut&paste from your input and I don't see a trailing space. The two leading spaces are annoying and unwanted.
    – doneal24
    Commented May 10, 2023 at 16:50

3 Answers 3

1

With this short awk (sub is sed like, to substitute a pattern or a regex):

var=130023432 awk -v var="$var" '$1==var{sub($1" "$2" ", ""); print}' file

or simply:

awk -v var="130023432" '$1==var{sub($1" "$2" ", ""); print}' file

/media/ismail/SSDWorking/book-collection/_Books/book 1.epub
1

You can use awk for this.

var="$var" awk '$1 == ENVIRON["var"] { $1 = $2 = ""; print substr($0, 3) }' logfile

Output using your example

/media/ismail/SSDWorking/book-collection/_Books/book 1.epub

I've avoided the awk -v var="$var" '...'} construct because -v processes its values for backslashes, etc. whereas an environment variable is left untouched. If you really want to go this route then try this (not POSIX):

awk -v var="${var//\\/\\\\}" '$1 == var { $1 = $2 = ""; print substr($0, 3) }' logfile
3
  • Note that you have 2 leading spaces in the output that OP don't want IMHO Commented May 10, 2023 at 21:18
  • @GillesQuénot thanks fixed, although I was sure awk was supposed to recalculate $0 after assignment to a field $1 Commented May 10, 2023 at 22:47
  • No, it's a pitfall. You confuse with $1=$1 to normalize spaces Commented May 10, 2023 at 23:41
0

sed

$ sed -En "s~$var[^/]*(.*)~\1~p" input_file

pcregrep

$ pcregrep -o1 "$var[^/]*(.*)" input_file

grep

$ grep -oP "$var[^/]*\K.*" input_file

awk

$ awk -v var="$var" '$1==var {print $(NF-1),$NF}' input_file

Output

/media/ismail/SSDWorking/book-collection/_Books/book 1.epub
1
  • no command works. error bad math expression: operand expected at ^/'``. The awk command output Duffy) (Z-Library).epub Commented May 11, 2023 at 8:39

You must log in to answer this question.

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