Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Formatting a TSV with long cells with column makes its readability very low. It simply breaks lines like this:

$ python3 -c 'for i in (1,2,3): print(((str(i)*50)+"\t")*3)' | column -s $'\t' -t

11111111111111111111111111111111111111111111111111  11111111111111111111111111111111111111111111111111  1111111111111111111
1111111111111111111111111111111
22222222222222222222222222222222222222222222222222  22222222222222222222222222222222222222222222222222  2222222222222222222
2222222222222222222222222222222
33333333333333333333333333333333333333333333333333  33333333333333333333333333333333333333333333333333  3333333333333333333
3333333333333333333333333333333

My question is, how do I format tsv (most likely csv as well) files, to make sure that when a maximum cell length (that can be set with a parameter) is reached, it's not just a line break, but data will start in a new line with the same indentation.

For above data, the result could be something like:

1111111111 1111111111 1111111111 
1111111111 1111111111 1111111111 
1111111111 1111111111 1111111111 
1111111111 1111111111 1111111111 
1111111111 1111111111 1111111111 

2222222222 2222222222 2222222222 
2222222222 2222222222 2222222222 
2222222222 2222222222 2222222222 
2222222222 2222222222 2222222222 
2222222222 2222222222 2222222222 

3333333333 3333333333 3333333333 
3333333333 3333333333 3333333333 
3333333333 3333333333 3333333333 
3333333333 3333333333 3333333333 
3333333333 3333333333 3333333333 
share|improve this question
add comment

1 Answer

I don't know if understand what to want to achieve, but perhaps this awk program is useful for you:

Content of script.awk:

{
    ## Number of blocks printed to output.
    block = 0 

    ## Get number of columns searching how many tabs exists in the line.
    ## I substract one because each line has a tab at the end and splits
    ## function count blank space after it like a new column.
    col_nums = split( $0, dummy, /\t+/ )
    --col_nums

    ## Incorrect line if it has not any tab. Omit it.
    if ( col_nums < 1 ) { 
        next
    }   

    ## Get number of chars of each block to output.
    ## 'max_cell_length' is an input argument provided by the user. It means
    ## number of chars to input by line.
    chars = max_cell_length / col_nums

    ## For each column...
    for ( i = 1; i <= NF; i++ ) { 

        ## This is the index where I begin to extract a substring. Zero is
        ## at first char.
        begin_idx = 0 

        ## Get for each column blocks of 'chars' characters. And repeat until
        ## end of column.
        while ( begin_idx < length( $i ) ) { 
            column = substr( $i, begin_idx, chars )

            ## Increment index to extract next block where last one ended.
            begin_idx += chars

            ## Print block to output.
            printf "%s ", column

            ## When have been printed number of columns indicated by the 
            ## user, change to next line.
            if ( ++block % col_nums == 0 ) { 
                printf "\n"
            }   
        }   
    }   
}

{
    ## For each line, print an extra newline for a pretty output.
    printf "\n"
}

Running the script:

python3 -c 'for i in (1,2,3): print(((str(i)*50)+"\t")*3)' | awk -v max_cell_length=30 -f script.awk -

And result:

1111111111 1111111111 1111111111 
1111111111 1111111111 1111111111 
1111111111 1111111111 1111111111 
1111111111 1111111111 1111111111 
1111111111 1111111111 1111111111 

2222222222 2222222222 2222222222 
2222222222 2222222222 2222222222 
2222222222 2222222222 2222222222 
2222222222 2222222222 2222222222 
2222222222 2222222222 2222222222 

3333333333 3333333333 3333333333 
3333333333 3333333333 3333333333 
3333333333 3333333333 3333333333 
3333333333 3333333333 3333333333 
3333333333 3333333333 3333333333 

You can use variable max_cell_length to indicate number of chars per line of output (without banks), and I suppose it will be a factor of number of chars in original data. Otherwise output will be bad formated, I tested it with 30, as you can see in this post, and with 50. Both seems correct but not with many other strange numbers.

share|improve this answer
add comment

Your Answer

 
discard

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.