0

Sample Input:

apple_ig
rabbit_cat_ig
dog_ig
bird_duck_ig
orange_ig
goat_ig

Expected output:

apple_ig
dog_ig
orange_ig
goat_ig

I need to ignore all data that contains underscore _ more than once in the entire string.

bash, ksh , sed, grep, awk

5 Answers 5

5
$ grep -v '_.*_' file
apple_ig
dog_ig
orange_ig
goat_ig
3

With awk, to print only lines having maximum one underscore.

$ awk -F_ 'NF<=2' file
apple_ig
dog_ig
orange_ig
goat_ig
0

Using sed

$ sed -n '/^[^_]*_[[:alpha:]]\+$/p' input_file
apple_ig
dog_ig
orange_ig
goat_ig
2
  • 2
    sed '/_.*_/d' would be more straightforward May 10 at 19:41
  • I'm not sure why you'd use [[:alpha:]] in the second instance though, it seems overly restrictive if the idea is to just count the underscores. Similarly, there's no need to require at least one character after the underscore -- and then there's the thing that \+ is undefined in standard BRE, so that command might not work on all systems. Also that would miss any lines that have no underscores at all. I think you'd have to do something like sed -n '/^[^_]*\(_[^_]*\)\{0,1\}$/p' to do that positive match on lines that contain zero or one underscores.
    – ilkkachu
    May 10 at 20:24
0

GNU sed we try to replace the second occurrence of _ and breakout on failureT, otherwise deleting the pattern space d.

sed 's/_/&/2;T;d' file

POSIX sed same as above but inverting the logic, since T command is a GNU add-on::

sed -n -e 's/_/&/2;t' -e 'p'file

awk

awk '!/(.*_){2}/' file

Perl in a scalar / void contexts the tr builtin emits a count of the number of transformations it does.

perl -pe '$_=$\ if tr/_// > 1' file
0
sed -n '/.*_.*_.*/!p' file.txt

output

apple_ig
dog_ig
orange_ig
goat_ig

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.