Home > Software design >  Echo multiple variables with delimiter and prevent new line (in code) being printed in the output
Echo multiple variables with delimiter and prevent new line (in code) being printed in the output

Time:01-21

I would like to print a number of variables in a tab-delimited manor, and for the sake of code cleanliness, I would like it write it like the below:

for f in files*
do
echo -e "
$var1\t
$var2\t
$var3\t
$var4\t
"
done
output:
file1_var1   file1_var2   file1_var3   file1_var4
file2_var1   file2_var2   file2_var3   file2_var4

I can get it to work like this, but it is not very tidy:

echo -e "$var1\t$var2\t$var3\t$var4\t"

I have tried using something like this to replace the new lines with tabs, but it seems a bit cumbersome. Also I need to add a new line at the end to prevent multiple files being printed on the same line, and it adds a new line between each output line as well.

for i in files*
do
echo -e "
$var1\t
$var2\t
$var3\t
$var4\t
| sed '$!{:a;N;s/\n/\t/;ta}' 
"
echo -e "\n"
done
output:
file1_var1   file1_var2   file1_var3   file1_var4

file2_var1   file2_var2   file2_var3   file2_var4

CodePudding user response:

Basically never use echo -e. You can almost always make it more elegant with printf, or simply cat

If you don't mind getting one spurious tab,

printf "%s\t" "$var1" "$var2" "$var3" "$var4"
printf '\n'

With a here document, you can write a simple sed script to replace all internal newlines with tabs.

sed 'N;N;N;s/\n/\t/g' <<:
$var1
$var2
$var3
$var4
:

(This is probably not entirely portable, but it works on MacOS and Ubuntu, so it should work most places you care about.)

Perhaps also look into pr, which can arrange things in a matrix.

printf "%s\n" "$var1" "$var2" "$var3" "$var4" | pr -bt4

(Again, probably not entirely portable, but works e.g. on Linux. On MacOS I had to remove the b option.)

It's not clear where the variables should come from; perhaps write a function to wrap printf if you just want to print its arguments in groups of four:

fourcols () {
    while [ $# -gt 4 ]; do
        fourcols "$1" "$2" "$3" "$4"
        shift 4  # not portable to sh
    done
    while [ $# -gt 0 ]; do
        printf "%s" "$1"
        shift
        if [ $# -gt 0 ]; then
            printf "\t%s" "$@"
        done
        printf "\n"
    done
}

Then you can just call fourcols * if you want to print all files in four columns, for example.

CodePudding user response:

Defining a function that joins its arguments as a TSV record:

tsvrecord() { first=$1; shift && printf '%s' "$first" "${@/#/$'\t'}"; echo; }

tsvrecord "$var1" "$var2" "$var3" "$var4"

remark: no TSV escaping is done here, so if a filepath contains \t or \n (which is allowed on Unix) then the resulting TSV will be broken.

  •  Tags:  
  • Related