我想创建一个包含两列的表。第一列包含键名,第二列包含值。该值可以是通常在终端中产生多行的文本。
使用printf
或column
,我可以轻松获得以下输出:
<----- Terminal Length ------>
key1 This is the value for
key1 with a very long text.
...
但我想将值显示在同一列中,如下所示:
<----- Terminal Length ------>
key1 This is the value for
key1 with a very long
text.
...
如何在同一列中包含长行?
答案 0 :(得分:2)
基于andlrc评论的解决方案:
columnize2 () {
indent=$1;
collen=$(($(tput cols)-indent));
keyname="$2";
value=$3;
while [ -n "$value" ] ; do
printf "%-10s %-${indent}s\n" "$keyname" "${value:0:$collen}";
keyname="";
value=${value:$collen};
done
}
longvalue=---------------------------------------------------------------------xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
columnize2 30 key1 $longvalue
key1 --------------------------------------------------
-------------------xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxzz
tput cols
返回终端窗口中每行的字符数。我们使用它来确定每行可以打印的值的字符数(collen
)。如果它不适合一行,则其余行打印在以下行上。
print语句中的%-10s
用于分配10个字符以显示键名(长键处理不好)。
%-${indent}s
用于通过#indent字符缩进值。
仅打印适合一行的值的多个字符:${value:0:$collen}
并从值value=${value:$collen}
中删除已打印的字符
对于以下行,我们不打印键名(通过将其设置为空字符串)。
答案 1 :(得分:0)
我正在写屏幕和文件,并且难以维护标签。我切换到间距因为它在屏幕/文件和linux / windows之间完全相同。下面是一些用空格填充字段的代码,以确保下一个字段与每个列项目的距离相等。如果你想填充开头,只需将空格移动到变量的开头而不是在&#34; sHeading =&#34;之后。线。如果你愿意,也可以使用Tab键进行相同操作。
\d
答案 2 :(得分:0)
实际上,util-linux的“ column”命令可以做到这一点。它非常通用。
#!/bin/bash
cat <<- EOF | column --separator '|' \
--table \
--output-width 30 \
--table-noheadings \
--table-columns C1,C2 \
--table-wrap C2
key1|Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
key2|blahhhhhhhhhhhhhhhhhhhhhhhhhhhhzzz
EOF
这给出了:
key1 Lorem ipsum dolor sit am
et, consectetur adipisci
ng elit, sed do eiusmod
tempor incididunt ut lab
ore et dolore magna aliq
ua.
key2 blahhhhhhhhhhhhhhhhhhhhh
hhhhhhhzzz
--output-width
:给出所需的大小(可以使用如上所述的“ tput cols”)
--table-columns C1,C2
:为要与其他选项结合使用的列命名
--table-wrap C2
:包装第2列
列版本:
# column -V
column from util-linux 2.33.1
答案 3 :(得分:0)
我最近在想同样的问题。我编写了一个名为printf-wrap
的小脚本来实现此功能,其灵感来自@phobic。之所以必要,是因为用户工作区上的column
版本可能没有包装功能,并且他/她也没有被授权安装或更新任何软件包。 (是的,用户是我...)
printf-wrap
接受与printf
相同的相同输入参数,并巧妙地包装 每列 。然后,您可以使用tput
将其调整为终端宽度。
# printf-wrap
# Description: Printf with smart word wrapping for every columns.
# Usage: print-wrap "<format>" "<text>" "<text>" ...
function printf-wrap {
# help info
help_message="Usage: print-column-wrap \"<format>\" \"<text>\" \"<text>\" ..."
if [[ "$1" =~ ^(-|--)?(h|help)$ ]] ; then echo "$help_message" ; return 0 ; fi
# parse argument
format="$1"
width=( $( echo "$format" | sed -r 's/%%|\\%//g' | sed -r 's/%/\n%/g' | sed -n -r 's/^%[^1-9]*([0-9]+).*/\1/p' ) )
shift
text=( "$@" )
error_message="Error: number of input text fields (${#text[@]}) MUST NOT EXCEED number of columns specified (${#width[@]}) !"
if (( ${#text[@]} > ${#width[@]} )) ; then echo "$error_message" ; return 1 ; fi
# printing
while [ -n "$( echo "${text[@]}" | sed -r 's/\s+//g' )" ] ; do
text_cut=()
width_cut=()
for i in ${!text[@]} ; do
text[$i]="$( echo "${text[$i]}" | sed -r 's/^\s+//' )"
if [[ "${text[$i]:${width[$i]}-1:2}" =~ [a-zA-Z0-9_]{2} ]] ; then
text_cut[$i]="$( echo "${text[$i]:0:${width[$i]}}" | sed -r 's/\w+$//' )"
else
text_cut[$i]="${text[$i]:0:${width[$i]}}"
fi
width_cut[$i]=${#text_cut[$i]}
text[$i]="${text[$i]:${width_cut[$i]}}"
done
printf "$format" "${text_cut[@]}"
done
}
输出看起来如下。
$ printf-wrap "%-10s %-$(( $(tput cols) - 11 ))s\n" "key1" "This is the value for key1 with a very long text"
============ Terminal Width ============
key1 This is the value for key1
with a very long text
希望这可以帮助任何人。 :)