Home > Blockchain >  Simplest way to create columns from variable's line content?
Simplest way to create columns from variable's line content?

Time:06-20

Is there a simple way to create columns using BASH's builtin programs or GNU equivalents from variables - one variable per column - that are the result of listing directories?

var1’s lines should be in column 1. var2’s lines should be in column 2.

I’m getting partway there, but failing to get isolated columns per variable’s line content.

var1=$( ls ./somedir1/* | ggrep ‘matching filetype1’ )

var2=$( ls ./somedir2/* | ggrep ‘matching filetype2’ )

I’ve tried:

paste <(printf %s "$var1”) <(printf %s "$var2”)

creates 2 columns but with var2’s lines starting below var1s in column 1 and indented to the right and then continues in column 2.

paste <(printf %s "$var1”) <(printf %s "$var2”) | column -t

gives clean columns (without the indent) but the same problem - var2’s lines start below var1s in column 1 and then continue in column 2.

CodePudding user response:

Do not process the output of ls but expand patterns as arguments, and use printf to format the output of file paths expanded as arguments.

paste <(cd somedir1 && printf '%-40s\n' *.filetype1) <(cd somedir2 && printf '%-40s\n' *.filetype2)

cd somedir1 Change directory to somedir1, && and conditionally printf '%-40s\n' *.filetype1 print formatted newline delimited file names that matches the *.filetype1 pattern. The format also ensures a 40 characters column width.

paste will combine both lists into side by side columns.

CodePudding user response:

By default paste uses a tab character for joining the lines while column uses a space character for splitting the columns, so you have to specify the delimiter in the column command:

paste <(printf %s "$var1") <(printf %s "$var2”) |
column -s "$(printf '\t')" -t

Aside from that, is ls ./somedir1/* really what you want? It's kind of equivalent to printf '%s\n' ./somedir1/* ./somedir1/*/*...

You could also get rid of the | ggrep 'matching filetype1' by using a more specific glob like ./somedir1/*.filetype1

CodePudding user response:

#!/bin/bash

column -t <(
  paste <(
     find /path/to/somedir1 -maxdepth 1 -type f -name "match1" -printf "%f\n"|sort
    ) \
    <(
     find /path/to/somedir2 -maxdepth 1 -type f -name "match2" -printf "%f\n"|sort
    )
)
  • Related