Efficient way to count number of intersections of line segments
Let's first assume there is no common boundaries between all segments.
Create the list of tuples ($pos$, $ind$) with a value ($pos$) for each boundary of every segment (thus $2n$ values) and $ind$ the index of the segment, sorted by $pos$. Sorting is achieved in $O(n \log(n)).$
Keep two counters, $open$, the number of opened segments and $close$, the number of closed segments. Both are initially at 0.
$E[i]$ will be an array of the segment $i$ state, where 0 means not opened yet, 1 otherwise.
$A[i]$ will be the $n$-element array to output, which are 0s initially.
Then loop through the list,
for tuple (pos, i),
    if E[i] == 0, then A[i] = close, open += 1, E[i] = 1
    else A[i] = open-A[i]-1, close += 1

The &quot;-1&quot; stands for a segment not counting himself.
This achieves $O(n)$, then still driven by the sorting $O(n \log(n))$.
Now, how to treat common boundaries ? In your exemple, I understand that segments are closed and for example [2, 7] does intersect [7, 8]. A simple way to do it (clearly not the most efficient but still $O(n)$), is to loop 3 times on the tuples at the same position:

first, you only count the opening segments in $open$
then, you only update $E[i]$ and $A[i]$ for both opening and closing segments
finally, you only count the closing segments in $close$ (that now have $E[i] = 2$)