Home > database >  Pass number of for loop elements to external command
Pass number of for loop elements to external command

Time:02-19

I'm using for loop to iterate through .txt files in a directory and grab specified rows from the files. Afterwards the output is passed to pr command in order to print it as a table. Everything works fine, however I'm manually specifying the number of columns that the table should contain. This is cumbersome when the number of files is not constant.

The command I'm using:

for f in *txt; do awk -F"\t" 'FNR ~ /^(6|9|24)$/{print $2}' $f; done | pr -ts --column 4

How should I modify the command to replace '4' with elements number?

The for loop generates the following from 4 *txt files:

1222327
105956
49271
969136
169119
9672
1297357
237210
11581
1189529
232095
13891

Expected pr output using a dynamically generated --column 4:

1222327 969136  1297357 1189529
105956  169119  237210  232095
49271   9672    11581   13891

CodePudding user response:

You could just run ls and pipe the output to wc -l. Then once you've got that number you can assign it to a variable and place that variable in your command.

num=$(ls *.txt | wc -l)

I forget how to place bash variables in AWK, but I think you can do that. If not, respond back and I'll try to find a different answer.

CodePudding user response:

I think he can use bash variable like $numin AWK

CodePudding user response:

Assumptions:

  • all input files generate the same number of output lines (otherwise we can add some code to keep track of the max number of lines and generate blank columns as needed)

Setup (columns are tab-delimited):

$ grep -n xxx f[1-4].txt
f1.txt:6:xxx    1222327
f1.txt:9:xxx    105956
f1.txt:24:xxx   49271
f2.txt:6:xxx    969136
f2.txt:9:xxx    169119
f2.txt:24:xxx   9672
f3.txt:6:xxx    1297357
f3.txt:9:xxx    237210
f3.txt:24:xxx   11581
f4.txt:6:xxx    1189529
f4.txt:9:xxx    232095
f4.txt:24:xxx   13891

One idea using awk to dynamically build the 'table' (replaces OP's current for loop):

awk -F'\t' '
FNR==1             { c=0 }
FNR ~ /^(6|9|24)$/ {   c ; arr[c]=arr[c] (FNR==NR ? "" : " ") $2 }
END                { for (i=1;i<=c;i  ) print arr[i] }
' f[1-4].txt | column -t -o ' '

NOTE: we'll go ahead and let column take care of pretty-printing the table with a single space separating the columns, otherwise we could add some more code to awk to right-pad columns with spaces

This generates:

1222327 969136 1297357 1189529
105956  169119 237210  232095
49271   9672   11581   13891
  • Related