stack_A
stack_A

Reputation: 763

check if elements of string exist in another string

I have two strings:

l1='a1 a2 b1 b2 c1 c2'
l2='a1 b3 c1'

And I want to check if each element of string l2 exists in l1, and then remove it from l1.

Is it possible to do that without a for loop?

Upvotes: 0

Views: 35

Answers (1)

Barmar
Barmar

Reputation: 781814

You can do this:

l1=$(comm -23 <(echo "$l1" | tr ' ' '\n' | sort) <(echo "$l2" | tr ' ' '\n' | sort) | tr '\n' ' ')

The comm compares lines and outputs the lines that are unique to the first input, unique to the second input, and common to both. The -23 option suppresses the second two sets of outputs, so it just reports the lines that are unique to the first input.

Since it requires the input to be sorted lines, I first pipe the variables to tr to put each word on its own line, and then sort to sort it. <(...) is a common shell extension called process substitution that allows a command to be used where a filename is expected; it's available in bash and zsh, for example (see here for a table that lists which shells have it).

At the end I use tr again to translate the newlines back to spaces.

DEMO

If you don't have process substution, you can emulate it with named pipes:

mkfifo p1
echo "$l1" | tr ' ' '\n' | sort > p1 &
mkfifo p2
echo "$l2" | tr ' ' '\n' | sort > p2 &
l1=$(comm p1 p2 | tr '\n' ' ')
rm p1 p2

Upvotes: 1

Related Questions