-4

I have a huge text. I want to remove all lines with only one . in it.

Sample input:

abc.google.org
yahoo.com
abc.yahoo.in
abcd.bing.com
abcd.xyz.bing.uk
abcd.xyz.mnp.bing.uk
stackexchange.com
yas.sxs.sxs.zs.sxstackexchange.com

Expected output:

abc.google.org
abc.yahoo.in
abcd.bing.com
abcd.xyz.bing.uk
abcd.xyz.mnp.bing.uk
yas.sxs.sxs.zs.sxstackexchange.com

I really appreciate any help you can provide.

2
  • 1
    There's probably a duplicate somewhere. You can use grep to look for lines with 2 or more . or use awk to split on . and select lines with at least three fields.
    – Sundeep
    Jun 20 at 4:47
  • 9
    What have you tried? Jun 20 at 5:25
8
awk -F'.' 'NF!=2' infile

not print those lines if that was containing only two fields (i. e, line with only a single dot was found). field separator can be specified with the -F option.


or using the gsub() function:

awk 'gsub(/\./, ".")!=1' infile

if number of successful replacements of the dot character (with itself) was other than one occurrence, print it.

0
4

Something like

grep -v '^[^.]*\.[^.]*$' input.txt

Print all lines that do not match a RE that looks for a single period in a line.

1
  • 2
    Use -x and we can then drop the line beginning and ending assertions.
    – guest_7
    Jun 20 at 16:33
3

Here is my sed solution, which uses the same regular expression as @shawn's grep:

sed -i.bak '/^[^.]*\.[^.]*$/d' FILE

It has the (dubious) advantage of working directly on the FILE (but it does write a FILE.bak with the original content). The regular expression takes a full line thanks to its anchors ^ and $. If this line consists of a string with zero or more non-dots [^.]*, followed by a single dot, followed by zero or more non-dots [^.]*, it will be deleted.

Tested with the sample input.

0
3

Another way to look at it is that you want the lines with at least 2 dots (assuming you don't want the lines with no dots). So:

LC_ALL=C grep '\..*\.' < input > outpu
2

POSIX sed:

  • Line with at least two dots print n Next.
  • What remains are line with exactly one or none dots. Of these, delete the dot carrying.
sed -e '/\..*\./b' -e '/\./d' file

GNU awk:

  • remove everything except dots and record the length of this resulting string and compare against one.
awk 'length(gensub(/[^.]/,"","g",t=$0))-1' file

GNU sed:

  • store line in hold space for later use.
  • Try removing a dot.
  • if you failed, print line and next read.
  • In case no dot remained => exactly one dot in original. So delete it.
  • Else, retrieve the original line as it had > 1 dots.
 sed -e 'h;s/\.//;T;//!d;g' file

Perl:

  • When the number of dot transliterations is one then assign the list separator($,) whose default value is empty string.
  • the -p option will autoprint the current record.
perl -pe 'y|.||-1||($_=$,)' file

Python:

  • list comprehension along with an if clause to select those lines that split into two or more or none fields.
python3 <<\eof
with open('file') as f:
  print(*[l for l in f if len(l.split('.')) != 2],sep='',end='')
eof

Standard grep in which multiple -e statements signify ORing

$ grep -e '\..*\.' -e '^[^.]*$' file
0
1
perl -lne 'print if tr/\.// > 1' data

Or

perl -F/\\./ -nle 'print if @F > 2' data
2
  • or maybe tr/\.// != 1 since they only mentioned removing lines with one dot, though they didn't make it at all clear what should be done with completely dotless lines.
    – ilkkachu
    Jun 20 at 14:17
  • Of course, but the sample data given shown domain names and domain names without dot aren't possibile. Jun 20 at 14:19

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.