#!/bin/sh
#!perl -w # --*- Perl -*--
eval 'exec perl -x $0 ${1+"$@"}'
    if 0;
#------------------------------------------------------------------------------
#$Author: saulius $
#$Date: 2022-09-28 06:59:33 +0000 (Wed, 28 Sep 2022) $
#$Revision: 812 $
#$URL: svn://saulius-grazulis.lt/scripts/tsv-transpose $
#------------------------------------------------------------------------------
#*
#
# Read a TSV [1] format file, transpose it (i.e. convert rows to
# columns and vice versa), and write out in TSV format again.
#
# Refs.:
#
# 1. Library of Congress. TSV, Tab-Separated
#    Values. https://www.loc.gov/preservation/digital/formats/fdd/fdd000533.shtml
#    [accessed: 2022-04-05T11:51+03:00]
# 
# Usage:
#     $0 --options
#     $0 --options input.csv* > output.tab
#**

use strict;
use warnings;

use Encode qw( decode );
use File::Basename qw( basename );

my $input_separator = "\t";

my @files;

my $i = 0;
while( $i <= $#ARGV ) {
    local $_ = $ARGV[$i];
    if( /^(-s|--separator|--separato|--separat|--separa|
           --separ|--sepa|--sep|--se|--s)$/x ) {
        if( $i >= $#ARGV ) {
            die "Option '$ARGV[$i]' ('--separator') needs " .
                "one character argument"
        } else {
            $i ++;
            $input_separator = $ARGV[$i];
            next;
        }
    }
    if( /^(-h|--help|--hel|--he|--h)$/ ) {
        open(SELF, $0) or die;
        local $\ = "\n";
        while( <SELF> ) {
            s/\$0/$0/g;
            print $1 if (/^\#\*/../^\#\*\*/) && /^\#\*?\*?(.*)$/;
        }
        close(SELF);
        exit
    }
    if( /^(--options|--option|--optio|--opti|--opt|--op|--o)$/ ) {
        print STDERR "$0: option '--options' is a placeholder, please use " .
            "\"$0 --help\" to get a list of available options\n";
        exit(2);
    }
    if( /^--$/ ) {
        @files = (@files, @ARGV[$i+1..$#ARGV]);
        last;
    }
    if( /^-/ ) {
        die "unknwon option '$_'";
    } else {
        push( @files, $_ );
    }
} continue {
    $i++;
}

@ARGV = @files;

binmode(STDIN,"utf8");
binmode(STDOUT,"utf8");
binmode(STDERR,"utf8");

my @transposed;

while (<>) {
    chomp;
    my @line = split($input_separator, $_);

    my $column = 0;
    for my $cell_value (@line) {
        push( @{$transposed[$column]}, $cell_value );
        $column ++;
    }
}

for my $row (@transposed) {
    local $, = "\t";
    local $\ = "\n";
    print @$row;
}
