Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Would you kindly help me to resolve the following?

20066898701..20066901700
20066891201..20066893700
20066879201..20066888700
20009429701..20009439700
20009412201..20009414700

I have an input as above

  1. I need to convert the .. to , seperated

  2. Then the column 2 will be subtracted from column 1 and output to be added with 1

20066898701..20066901700 => (20066901700-20066898701)+1 => 3000

share|improve this question
    
You say "column 2 will be subtracted from column 1" but your example shows column 1 subtracted from column 2. – Dennis Williamson Nov 9 '10 at 14:22

Pipe your output into the following Perl:
perl -ne 'my @fields = split /\s/, $_; foreach my $input (@fields) { if (/^(\d+)..(\d+)$/) { print $2 - $1 + 1, "\n"; } }'

What this does is firstly split the input on spaces (so your first line should work). It then runs a regular expression on each entry to match a string which only contains two numbers separated by .. - the brackets put the numbers in $1 and $2.

For example: echo "20066898701..20066901700" | perl -ne 'my @fields = split /\s/, $_; foreach my $input (@fields) { if (/^(\d+)\.\.(\d+)$/) { print $2 - $1 + 1, "\n"; } }' 3000

share|improve this answer
sed 's/\.\./,/g'<erk|awk 'BEGIN { FS = ","}; { total = ($2 - $1) +1; print total}

Given a file named "erk", containing your data:

tom@holborn:~$  cat erk | sed 's/\.\./,/g'| awk 'BEGIN { FS = ","}; { total = ($2 - $1) +1; print total}'
3000
2500
9500
10000
2500

You could pipe the output of your application straight into sed, instead of cat

share|improve this answer
    
sed is unnecessary. – jlliagre Nov 9 '10 at 22:22
    
sed is nice, though. – Tom O'Connor Nov 10 '10 at 10:06
    
Indeed, I meant sed is unnecessary in your code, but I like very much sed nevertheless. – jlliagre Nov 11 '10 at 14:23
    
I tend to write scripts in left-to-right order, so sed is the most straightforward way to do the first bit, then I think.. Ooh. Awk can do the next bit.. etc etc. – Tom O'Connor Nov 11 '10 at 14:42

In Bash:

while IFS=. read -r field1 null field2
do
    echo $((field2 - field1 + 1))
done < inputfile
share|improve this answer
for i in 20066898701..20066901700 20066891201..20066893700 20066879201..20066888700 20009429701..20009439700 20009412201..20009414700
do
    echo $i | awk -F "[.]+" '{ printf("%s\n",$2-$1+1); }'
done
3000
2500
9500
10000
2500

If the values are in a single line as it seems now, you can use the simpler:

awk -F "[.]+" '{ printf("%s\n",$2-$1+1); }' filename
share|improve this answer
    
Perhaps your for loop is just for demonstration, but if not it's a very inefficient way to do that. – Dennis Williamson Nov 9 '10 at 14:21
    
The initial question was showing all values in a single line. It has been edited to show them in multiple lines after my reply. I'm providing a simpler solution now. Of course, launching an awk command for every data pair is highly inefficient but might be "unnoticeably" inefficient if the number of values is not significantly large. – jlliagre Nov 9 '10 at 15:34

In bash:

cat file-with-numbers.txt | while read i
do
  first=`echo $i | cut -f1 -d.`
  second=`echo $i | cut -f3 -d.`
  expr $second - $first + 1
done
share|improve this answer
perl -pe 's/(\d+)\.\.(\d+)$/sprintf "%d,%d,%d",$1,$2,($2-$1)+1/eg;' filename

or

perl -pe 's/(\d+)\.\.(\d+)$/($2-$1)+1/eg;' filename  

if you only want the difference

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.