0

I have file that looks like that:

t # 3-7, 1
v 0 104
v 1 92
v 2 95
u 0 1 2
u 0 2 2
u 1 2 2
t # 3-8, 1
v 0 94
v 1 13
v 2 19
v 3 5
u 0 1 2
u 0 2 2
u 0 3 2
t # 3-9, 1
v 0 94
v 1 13
v 2 19
v 3 7
u 0 1 2
u 0 2 2
u 0 3 2

t corresponds to header of each block.

I would like to extract multiple patterns from the file and output transactions that contain required patterns altogether.

I tried the following code:

ps | grep -e 't\|u 0 1 2' file.txt 

and it works well to extract header and pattern 'u 0 1 2'. However, when I add one more pattern, the output list only headers start with t #. My modified code looks like that:

ps | grep -e 't\|u 0 1 2 && u 0 2 2' file.txt 

I tried sed and awk solutions, but they do not work for me as well.

Thank you for your help! Olha

3
  • 1
    Why did you use && instead of \| like when you added the second pattern? Commented Aug 13, 2020 at 21:11
  • 1
    @anubhava The t lines don't have 0 1 2 on them. Commented Aug 13, 2020 at 21:15
  • Ah that's right, in that case grep -E 'u 0 [12] 2|t' Commented Aug 13, 2020 at 21:17

3 Answers 3

1

Use | as the separator before the third alternative, just like the second alternative.

grep -E 't|u 0 1 2|u 0 2 2' file.txt

Also, it doesn't make sense to specify a filename and also pipe ps to grep. If you provide filename arguments, it doesn't read from the pipe (unless you use - as a filename).

Sign up to request clarification or add additional context in comments.

2 Comments

So, this give me both options, t # 3-436, u 0 1 2, u 0 2 2 and t # 3-437, u 0 1 2. How can I keep exact match (meaning t # 3-436, u 0 1 2, u 0 2 2 only)?
You mean you only want the t # line if there were u lines matched in that block? I don't think you can do that with grep, you need something programmable like awk.
1

You can use grep with multiple -e expressions to grep for more than one thing at a time:

$ printf '%d\n' {0..10} | grep -e '0' -e '5'
0
5
10

Comments

0

Expanding on @kojiro's answer, you'll want to use an array to collect arguments:

mapfile -t lines < file.txt
for line in "${lines[@]}"
do
    arguments+=(-e "$line")
done

grep "${arguments[@]}"

You'll probably need a condition within the loop to check whether the line is one you want to search for, but that's it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.