0

I am writing a bash shell script that has to do multiple things. The function I am currently working on needs to transpose a matrix, which in this case is just a text file that has Rows and Columns. I have two files that I call m1 and m2... m1 text file is just this :

1 2 3
4 5 6

m2 =

1 5
2 6
3 7
4 8

So essentially I need to make m2 into m1 and m1 into m2. Here is my code so far, which I got most of it from an in-class lecture on transposing which helped a lot. It is currently not printing out anything but it still runs and doesn't have run time errors.

Here is my code:

transpose)

inputFile="tempinputfile"
tempCol="tempcolfile"
tempRow="temprowfile"


echo -e "1\t2\t3\t4\t5" > $inputFile

cut -c 1 $inputFile > $tempCol
cut -c 3 $inputFile >> $tempCol
cut -c 5 $inputFile >> $tempCol
cut -c 7 $inputFile >> $tempCol
cut -c 9 $inputFile >> $tempCol

cat $tempCol | tr '\n' '\t' > "$tempRow$$"

echo >> "$tempRow$$"




;;
  • ask yourself, 'which of the cmds I know so far are meant to "print out" a file?' It's already in your script, you just have to give it the correct filename to work ;-) . Good luck. – shellter Oct 13 '19 at 23:28
  • Thank you! I'll go back through my code and see what I can get :) –  Oct 13 '19 at 23:31
  • I understand how to print out a file. I need to call argument 2 in my code which would just be $2, but ive played around with this and I cant figure out which one i need to give it the correct file for –  Oct 14 '19 at 00:09
  • 1
    consider walking through your code, one line at a time, manually executing each line at the (linux) prompt; does each command do what you think it's supposed to do? – markp-fuso Oct 14 '19 at 00:09
  • Given file **m1**, it looks like file **m2** should begin with *"1 4"*, not *"1 5"*. – agc Oct 14 '19 at 01:18
  • If you have datamash installed: https://www.gnu.org/software/datamash/examples/#example_transpose – Shawn Oct 14 '19 at 01:20
  • You write "So essentially I need to make m2 into m1 and m1 into m2.". But you don't just want to swap the filenames? The result will be the same. Save m1 to a tmp file, copy/move m2 to m1 and then copy/move the temp to m2? You can keep all the extra processing but this is still what needs to be done. ALSO you wrote "It is currently not printing out anything but it still runs", hence my original comment. Where do you mention $2 in you the body of your Q? Best to revisit your Q and make your problem description more specific. Good luck. – shellter Oct 14 '19 at 02:42
  • See: the many answers in [An efficient way to transpose a file in Bash](https://stackoverflow.com/q/1729824/6136214), some of which are pure `bash`. – agc Oct 14 '19 at 07:16

2 Answers2

0

Have you worked with 2-dimensional arrays? Once the data has been loaded into the array (eg, arr[x,y]) a 'transpose' operation would just consist of looping through the y and x indices.

I find arrays in awk to be a bit easier to work with than arrays in bash; here's a awk hint:

awk '

BEGIN { arr[1][1]="a" ; arr[1][2]="b"
        arr[2][1]="c" ; arr[2][2]="d"
      }

END { printf "+++++++++++ as is\n"
      for (x in arr)
          { for (y in arr[x])
                { printf "%s ",arr[x][y] }
            printf "\n"
          }
      printf "+++++++++++ transposed\n"
      for (x in arr)
          { for (y in arr[x])
                { printf "%s ",arr[y][x] }
            printf "\n"
          }
      printf "+++++++++++\n"
    }
' m1

+++++++++++ as is
a b
c d
+++++++++++ transposed
a c
b d
+++++++++++

In your case you'd want to replace the entire BEGIN block with code that populates the array (arr[][]) with data from your file; an additional hint: look up the awk variables 'NF' and 'NR'.

A solution based on awk has the added benefit that it only scans the input file once; and since file IO incurs a (relative) high overhead, the fewer times you have to process the file the faster your code's going to run.

markp-fuso
  • 28,790
  • 4
  • 16
  • 36
  • Ah! I wish we could use AWK.. we cant use built in commands like that or ruby etc. –  Oct 13 '19 at 23:53
  • 1
    @AndrewWhite You can't use awk but you can use cut, tr, etc.? What's the limit on what programs you can call from the script? – Shawn Oct 14 '19 at 00:33
  • @Shawn Can't use awk ruby tcl perl –  Oct 14 '19 at 00:38
0
awk '{ for (i=1; i<=NF; i++) a[i]=(a[i]? a[i] FS $i: $i) } END{ for (i in a) print a[i] }' file.txt
agc
  • 7,973
  • 2
  • 29
  • 50
Šerg
  • 793
  • 5
  • 18