我编写了以下代码来显示按列格式化的数据:
str1='hello i am robert
and your ma frnd'
str2='thisisaverylongword thisistoohehehe andherefinishthe string
hereis a other linefortheexample'
IFS=$'\n'
echo '----------------------'
echo 'STRING SHORT'
echo '----------------------'
echo "$str1" | column -t
echo
echo '----------------------'
echo 'STRING LONG'
echo '----------------------'
echo "$str2" | column -t
哪个输出:
----------------------
STRING SHORT
----------------------
hello i am robert
and your ma frnd
----------------------
STRING LONG
----------------------
thisisaverylongword thisistoohehehe andherefinishthe string
hereis a other linefortheexample
好的,现在我尝试使用相同的模式格式化字符串,但不合并它们。
这是我正在寻找的结果:
----------------------
STRING SHORT
----------------------
hello i am robert
and your ma frnd
----------------------
STRING LONG
----------------------
thisisaverylongword thisistoohehehe andherefinishthe string
hereis a other linefortheexample
你有什么想法去做吗?可能会合并字符串并在格式之前将其拆分?
请注意,这只是一个示例,我正在寻找通用的解决方案,而不仅仅是针对此特定情况。
答案1
你不得不
printf "%s\n" "$str1" "$str2" | column -t
和然后注入标头
一般来说,我会写这样使用数组的东西:
strings=( "$str1" "$str2" ... )
headers=( "STRING SHORT" "STRING LONG" ... )
exec 3< <( printf "%s\n" "${strings[@]}" | column -t )
for (( i=0; i<${#strings[@]}; i++)); do
printf -- "----\n%s\n----\n" "${headers[i]}"
n=$(wc -l <<< "${strings[i]}")
for (( j=1; j<=n; j++ )); do
IFS= read -r line <&3
echo "$line"
done
echo
done
exec 3<&-
笔记:
<( ... )
是一场狂欢流程替代。这是一个作为文件名处理的普通管道。当您使用管道但无法在子 shell 中执行管道的右侧时,这非常方便。- 在这里,我们打开文件描述符#3来从此“文件”读取数据:
exec 3<file
read -r line <&3
从进程替换中读取一行数据exec 3<&-
关闭文件描述符- 在这里阅读有关重定向的更多信息:http://www.gnu.org/software/bash/manual/bashref.html#Redirections
- 我本来可以使用 a
printf ... | while read line; do ...; done
但我认为 for 循环会让计数更容易。