• Uncategorized

About linux : how-to-use-basic-linux-command-to-count-the-number-of-dot-in-every-line-then-insert-the-value-in-each-line-in-bash

Question Detail

I process a text file with many domain like

abcd.efgh.ijkl.mnop

I hope to add a 3 at the same line no matter how it is at the beginning or at the end.

current I use

sed 's/[^.]//g' thetextfile | awk '{ print length }' > thenumber

then I use librecalc to combine them.

Question Answer

In plain bash, without using any external utility:

#!/bin/bash

while read -r line; do
    dots=${line//[^.]}
    printf '%d\t%s\n' ${#dots} "$line" 
done < file

Using a perl one-liner, taking advantage of tr returning the number of changes:

$ perl -ne 'print tr/././, " ", $_' input.txt
3 abcd.efgh.ijkl.mnop
6 abcd.efgh.ijkl.mnop...
4 abcd.efgh.ijkl.mnop.

The blindingly obvious answer is

awk -F . '{ print NF-1, $0 }' thetextfile >thenumber

Combining the results to a single file in an external utility seems like a humongous overcomplication; just process all the files in one go.

awk -F . '{ print NF-1, $0 }' * >allnumbers

or if your needs are more complex maybe something like

for file in *.txt; do
    echo "$0: processing $file ..." >&2
    awk -F . '{ print NF-1, $0 }' "$file"
done >allnumbers

The -F . says to use the literal dot as field separator, and NF is the number of fields (which will be one more than the number of separators; look up “fencepost error” if you don’t understand why).

In more complex cases still, maybe append the output from each file with >>allnumbers inside the loop if you really need to (but understand that this is less efficient than only writing once after the done).

Awk’s default output field separator is a single space; if you want to produce TSV (tab-separated output) or CSV, you can set OFS="\t" or OFS="," as required.

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.