Homap
Homap

Reputation: 2214

Remove a line if all fields match a specific pattern

If I want to remove a line with a specific pattern in one field, for example the third field, I could write:

awk '$3!='pattern' file

If I want to remove lines in which all fields match a specific pattern, how could I do that? Here is an example file:

number1 1245 1/2 1/2 1/2 1/2
number2 1468 1/1 1/2 2/2 1/2

I want to remove the first line in this case as all fields after the second field contain 1/2 with no exception.

Thanks.

Upvotes: 1

Views: 86

Answers (3)

123
123

Reputation: 11216

Using sed

sed '\`^\([^[:space:]]\+[[:space:]]\+\)\{2\}\(1/2[[:space:]]\+\)\+1/2[[:space:]]*$`d' file

with -r/-E flag

sed -r '\`^([^[:space:]]+[[:space:]]+){2}(1/2[[:space:]]+)+1/2[[:space:]]*$`d' file

Assuming only spaces are used and not other whitespace characters.

sed -r '\`^([^ ]+ +){2}(1/2 +)+1/2 *$`d' file

Using awk

awk '{for(i=3;i<=NF;i++)if($i!="1/2")next;print}' file

Prints

number2 1468 1/1 1/2 2/2 1/2

Upvotes: 2

Kusalananda
Kusalananda

Reputation: 15633

Use sed for simple line-oriented editing like this:

$ sed '/pattern/d' input

In this case, you want to remove all line that has four consecutive occurrences of "<space>1/2" at the end of the line:

$ sed '/\( 1\/2\)\{4\}$/d' input

Alternatively,

$ sed -E '/( 1\/2){4}$/d' input

(if you have GNU sed, use -r instead of -E. I'm on a BSD system and use BSD sed)

UPDATE: Thanks to @EdMorton for commenting that you may get rid of the somewhat ugly \/ in the pattern in the following way:

$ sed '\:\( 1/2\)\{4\}$:d' input

or

$ sed -E '\:( 1/2){4}$:d' input

That may not matter much in this case, but sure makes the whole thing a lot easier to read in more complicated sed editing scripts.

Upvotes: 1

Ed Morton
Ed Morton

Reputation: 204064

$ awk '{delete cnt; for (i=3;i<=NF;i++) cnt[$i]++} cnt["1/2"] < length(cnt)' file
number2 1468 1/1 1/2 2/2 1/2

Upvotes: 0

Related Questions