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.

I'm trying to write a simple script, that just rotates csv table. I mean I have some file:

head1;head2;head3
field11;field12;field13

and so on. All I want, just to make my file

head1;field11;field21
head2;fielad12;field22
head3;field13;field23

I even haven't any idea about how it may work. I don't ask you to write a script, I need idea about how I can maje it in standart shell (unfortunately I'm not able to use bashism or gnu extensions, POSIX only)

ps. Actually I can do it, but only in ugly way with unbelievable enefficient multirereading file with table. I believe there is more beautiful way.

share|improve this question
2  
    
@dying_sphynx Almost... This is a more general case, because the separators make some difference. I gave an example of bash adaptation for semicolons below and let others decide whether the difference is enough to call this question unique. –  rozcietrzewiacz Mar 26 '12 at 16:16
    
Actually I just couldn't find this question on SO. It's pretty similar and seems to me the difference in separator isn't enough to make this question unique. Thank you for link on original question. –  rush Mar 26 '12 at 16:35

2 Answers 2

Here's a quick adaptation of the bash solution to this similar SO question for the particular separators you have (semicolons):

declare -a array=( )                      # we build a 1-D-array

IFS=';' read -a line < "$1"                       # read the headline

COLS=${#line[@]}                          # save number of columns

index=0
while IFS=';' read -a line ; do
    for (( COUNTER=0; COUNTER<${#line[@]}; COUNTER++ )); do
        array[$index]=${line[$COUNTER]}
        ((index++))
    done
done < "$1"

for (( ROW = 0; ROW < COLS; ROW++ )); do
  printf "%s" ${array[$ROW]}
  for (( COUNTER = ROW+COLS; COUNTER < ${#array[@]}; COUNTER += COLS )); do
    printf ";%s" ${array[$COUNTER]}
  done
  printf "\n" 
done
share|improve this answer
    
Thanks. That work pretty good. –  rush Mar 26 '12 at 16:35
    
PS. Actually solution with awk that is in SO works much better. But thank you anyway. –  rush Mar 26 '12 at 18:08
    
@rush Yes, awk is much faster in this kind of operations. It is definitely worth learning! I myself don't know it well enough yet, so I proposed a bash way. –  rozcietrzewiacz Aug 24 '12 at 15:41
flds=3; for((i=1;i<=flds;i++));do
  printf '%s' "$(cut -d';' -f$i file)" |tr '\n' ';';echo
done
share|improve this answer
    
Thanks, but that's not the solution I'm looking for. In this case I need read file as many times as columns I have. It's useful only for small files. Not my case. –  rush Mar 26 '12 at 18:07

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.