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.
