2

I have four files (file_one to file_four), the contents of these files isn't really important. I want to pass three of these files to a command (i.e. paste or awk) in a particular order as defined by an array. My array is order=(two one four). I was hoping to use the array to pass the desired files to the command as input similarly as how you could use * (i.e. paste file_* > combined_file);

paste file_${order[@]} > combined_file

paste file_"${order[@]}" > combined_file

paste file_"${order[*]}" > combined_file

paste file_"{${order[@]}}" > combined_file

paste file_{"${order[@]}"} > combined_file

I have looked at different pages (1, 2, 3 or 4) but I can't get it to to work. A loop through the files doesn't work in the case of paste or awk. I want to pass the files all at once to a command. Seeing as my UNIX knowledge is limited I may have misinterpreted some solutions/answers. From what I understand from this answer there might be some issues with how arrays were originally developed in bash.

Desired result: paste file_two file_one file_four > combined_file

tstev
  • 607
  • 1
  • 10
  • 20
  • Doing `paste file_* > combined_file` should work. What error are you getting – Inian Jul 03 '18 at 10:10
  • I know it does, but if you read my problem statement its not what I want. I want a particular order and not all the files. I will remove that to avoid confusion. Please see my desired result :) – tstev Jul 03 '18 at 10:20

2 Answers2

2

You could use printf:

paste $(printf "file_%s " ${order[@]}) > combined_file

This avoids having to loop through all elements of the order array.


Alternatively, using bashism, you could use this:

paste ${order[@]/#/file_} > combined_file

Note the # that matches the start of the pattern as mentioned in the bash man page:

${parameter/pattern/string}

(...) If pattern begins with #, it must match at the beginning of the expanded value of parameter.

oliv
  • 12,690
  • 25
  • 45
  • Awesome, it works! Although with your second solution - if the array is empty or non-existent it just seems to hang. I used wrong array and it seemed to be taking forever before I had to `CRTL+C` the operation. I like the solution without looping through the array. So for that reason I have chosen this as the answer. – tstev Jul 03 '18 at 14:20
1

You can have the for loop within $():

paste $(for i in ${order[@]}; do echo file_$i; done) > output_file
tstev
  • 607
  • 1
  • 10
  • 20
simon3270
  • 722
  • 1
  • 5
  • 8