1

I'm just starting in bash to make the legwork for an internship easier. So I'm not very good and sorry in advance if my initial attempt is so off the mark as to be not helpful. Please don't hesitate to ask for clarification.

My input resembles:

Set1
1
2
3
4
Set2
5
6
7
8

I would like my output to be:

group1  1   5
group1  2   6
group2  3   7
group2  4   8

So I could do

A=$(sed -n '2p' input)
B=$(sed -n '7p' input)

printf "group1\t$A\t$B" >> output

and repeat this 3 more times.

The problem is that instead of 2 groups of 4 numbers each, I actually have 7 groups of 34 numbers each, so something like 200-300 total. That's why I'd like to make a script that will automate this task.

For the first 17 numbers (group1), I had:

#!/bin/bash


##############################################################################
#group1


for (( i=0; i<=16; i++ )) ;
do

A=$(echo "scale=1;x=2+$i; x" |bc -l)

B=$(echo "scale=1;x=128+$i; x" |bc -l)

C=$(sed -n "$Ap" input)

D=$(sed -n "$Bp" input)

printf "group1\t$C\t$D\n" >> output


done   

Of course it doesn't work at all, probably for many reasons. For one thing, I haven't actually been able to use sed to filter a specific line using a variable as the input for the line number.That's my current error, but I suspect there will be more beyond that. I'm more than open to other approaches.

  • Is there an automated way to take two line numbers as input and arrange them in columns along a single line?
  • Is there an automated way to make this single line begin with another column eg. group1/group1/group2/group2?

Thank you for any advice.

  • You're using the wrong tools (and as a result you're processing the input hundreds of times). You can do it in one go with awk e.g. awk '/Set/{n=0; next}{++n;z[n]=z[n]" "$0}END{ for (k in z) printf("%s%s%s\n", "group", k, z[k])}' infile - I'm almost sure this is a dupe... – don_crissti Jan 31 '17 at 20:34
3

If you want something quick'n'dirty just to columnize the data, you could try pr

pr -t -2 input
Set1                                Set2
1                                   5
2                                   6
3                                   7
4                                   8

pr -t -7 input17x7
Set1      Set2      Set1      Set2      Set1      Set2      Set1
1         a         1         a         1         a         1
2         b         2         b         2         b         2
3         c         3         c         3         c         3
4         d         4         d         4         d         4
5         e         5         e         5         e         5
6         f         6         f         6         f         6
7         g         7         g         7         g         7
8         h         8         h         8         h         8
9         i         9         i         9         i         9
10        j         10        j         10        j         10
11        k         11        k         11        k         11
12        l         12        l         12        l         12
13        m         13        m         13        m         13
14        n         14        n         14        n         14
15        o         15        o         15        o         15
16        p         16        p         16        p         16
17        q         17        q         17        q         17

For better control, there's the rs utility. For example, you could do:

{ printf 'Group\n' ; printf 'group%d\n' {1..17} ; cat input17x7; } | rs -et 18 8
Group    Set1     Set2     Set1     Set2     Set1     Set2     Set1
group1   1        a        1        a        1        a        1
group2   2        b        2        b        2        b        2
group3   3        c        3        c        3        c        3
group4   4        d        4        d        4        d        4
group5   5        e        5        e        5        e        5
group6   6        f        6        f        6        f        6
group7   7        g        7        g        7        g        7
group8   8        h        8        h        8        h        8
group9   9        i        9        i        9        i        9
group10  10       j        10       j        10       j        10
group11  11       k        11       k        11       k        11
group12  12       l        12       l        12       l        12
group13  13       m        13       m        13       m        13
group14  14       n        14       n        14       n        14
group15  15       o        15       o        15       o        15
group16  16       p        16       p        16       p        16
group17  17       q        17       q        17       q        17

If you don't want the header, pipe the result via tail -n +2

  • Thank you for these commands. They look promising. Unfortunately I am getting a couple of errors. When I try the pr method, the input17x7 doesn't work (I am using 17x2). It treats 17x7 as an input file not as a description of the size of the matrix (pr: energies.in17x2: No such file or directory) When I try the rs utility, I get line 7: syntax error near unexpected token }' line 7: $ { printf 'Group\n' ; printf 'group%d\n' {2..18} ; cat energies.in17x2; } | rs -et 18 3' any ideas why? Thanks. – Blaise Feb 1 '17 at 13:23
  • Hell I cannot seem to format the above comment to make it readable and in code. Sorry for it looking so messy. – Blaise Feb 1 '17 at 13:26
  • For the first error I don't know - input17x7 was just my test file name since you didn't provide any appropriate data - its shouldn't have anything to do with the actual command that's run (it's the -7 argument that determines the number of output columns). For the second error, it sounds like you are using a POSIX sh shell rather than bash that you tagged your question with. Or did you include the $ shell prompt from my answer? That's not part of the command. – steeldriver Feb 1 '17 at 13:39
  • Ah the $ at the start must have been the issue. I have been reading tutorials on these commands and have decided to make 3 input files and use PR to sort them into one output of 3 columns, according to here: docstore.mik.ua/orelly/unix3/upt/ch21_15.htm .... I ran into a problem with a for do loop, though: i.imgur.com/ECoXAe9.png .... The loop of course executes each print command before starting over, yielding a column of 2.0, 2.5, 3.0...Is it possible to fully iterate one command before the next, so my output has 17 lines of 2.0, then 17 lines of 2.5, then 17 lines of 3.0 etc. ? – Blaise Feb 1 '17 at 14:40
  • @Blaise if you have additional requirements then please edit your original question rather than posting them as comments - please post text rather than images of text. – steeldriver Feb 1 '17 at 14:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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