Diagonal Output of a file

awk solution, not as elegant as @don_chrissti solution, but works where not a square.

awk -F, '{a=a$++n" "}END{print a}' file

Python and numpy

The input data that we're looking at can be treated as a matrix or 2-dimensional array. Now, if we approach the problem from this point of view, there's several computational tools that can be used for manipulating matrices. In particular, Python's numpy module allows that. Thus, we could use two things - the loadtxt() function and diagonal() to extract the desired data:

$ python -c 'import sys,numpy;a=numpy.loadtxt(sys.argv[1],dtype=int,delimiter=",");print( a.diagonal() )'  input.txt                                                                    
[1 7 3 9 5]

Now, this is the big chunk of the job done. To make the output pretty, we just need to convert the obtained data to strings, and create a space-separated string out of individual ones. Like so:

$ python -c 'import sys,numpy;a=numpy.loadtxt(sys.argv[1],delimiter=",");print(" ".join( [ str(int(i)) for i in a.diagonal() ]))'  input.txt                                            
1 7 3 9 5

Of course, all this doesn't have to be done as one-liner. For the sake of readability we can make a small script, which will also allow us to process all filenames given as arguments on command-line:

#!/usr/bin/env python
import sys
import numpy as np

for filename in sys.argv[1:]:
    data=np.loadtxt(filename,delimiter=",")
    diag = data.diagonal()
    result_string = " ".join( [ str(int(i)) for i in diag ] ) 
    print(result_string)

  1. POSIX shell:

    n=0
    while IFS=',' && read x ; do
        set -- $x ; shift $n ; echo "$1" ; n=$((n+1))
    done < inputfile
    
  2. bash can be more concise:

     n=0; while IFS=',' read -a x ; do echo "${x[((n++))]}" ; done < inputfile
    

Note that it's easy to get diagonals for all four rotations of the data by filtering to tac and rev, (or tac alone -- if the data is a square .csv array). POSIX shell examples, but first make some new asymmetric input values:

seq 25 | paste -d, - - - - - | tee asym_input

Output:

1,2,3,4,5
6,7,8,9,10
11,12,13,14,15
16,17,18,19,20
21,22,23,24,25
  1. A \ left to right diagonal, (the OP question, with different input):

    n=0
    while IFS=',' && read x ; do
         set -- $x ; shift $n ; echo "$1" ; n=$((n+1))
    done < asym_input
    

    Output:

    1
    7
    13
    19
    25
    
  2. A / left to right diagonal:

    n=0
    tac asym_input | while IFS=',' && read x ; do
         set -- $x ; shift $n ; echo "$1" ; n=$((n+1))
    done
    

    Output:

    21
    17
    13
    9
    5
    
  3. A / right to left diagonal:

    n=0
    rev asym_input | while IFS=',' && read x ; do
         set -- $x ; shift $n ; echo "$1" ; n=$((n+1))
    done | rev
    

    Output:

    5
    9
    13
    17
    21
    
  4. A \ right to left diagonal:

    n=0
    tac asym_input | rev | while IFS=',' && read x ; do
         set -- $x ; shift $n ; echo "$1" ; n=$((n+1))
    done | rev
    

    Output:

    25
    19
    13
    7
    1