如何对齐具有多行的第 n 列
How to align the nth column that has multiple lines
我有 3 个变量,我使用 printf 来对齐它们的输出
我知道第一个环境变量是一行,所以第二个变量也是
第三个变量的问题是这个变量有巨大的输出因此我想列出它们对齐(我希望下面会清除我的问题)
** 我没有列命令 **
我正在使用
printf "%-20s %-5s %-20s \n" "${OUT}" "${COUNT}" "${DATA}"
OUT11 OUT2 OUT3
---------- ----- --------------
GATE1 14 CU4 CU2 CU9var CU3 CU1 CU11admin CU10opt not_sy
CU_doonce cutttCU clocal_CU global_CU tivoli_CU
GATE2 70 gdba_CU cdba_CU vudb_CU tti1_CU tti3_CU tt3_CU
3c2_CU tt3c3_CU tt3c4_CU tt3d1_CU tt3a1_CU tt3u1
3t3_CU tt3t4_CU tt4_CU utt4_CU tt4c1_CU tt4c2_CU
4d1_CU tt4a1_CU tt4u1_CU tt4t1_CU tt4t2_CU tt4t3
tt5_CU tt5c1_CU tt5c2_CU tt5c3_CU tt5c4_CU tt5d1
5t1_CU tt5t2_CU tt5t3_CU tt5t4_CU tt6_CU utt6_CU
6c3_CU tt6c4_CU tt6d1_CU tt6a1_CU tt6u1_CU tt6t1
6t4_CU tt7_CU utt7_CU tt7c1_CU tt7c2_CU tt7c3_CU
7a1_CU tt7u1_CU tt7t1_CU tt7t2_CU tt7t3_CU tt7t4
我需要它们:
OUT11 OUT2 OUT3
---------- ----- --------------
GATE1 14 CU4 CU2 CU9var CU3 CU1 CU11admin CU10opt not_sy
CU_doonce cutttCU clocal_CU global_CU tivoli_CU
GATE2 70 gdba_CU cdba_CU vudb_CU tti1_CU tti3_CU tt3_CU
3c2_CU tt3c3_CU tt3c4_CU tt3d1_CU tt3a1_CU tt3u1
3t3_CU tt3t4_CU tt4_CU utt4_CU tt4c1_CU tt4c2_CU
4d1_CU tt4a1_CU tt4u1_CU tt4t1_CU tt4t2_CU tt4t3
tt5_CU tt5c1_CU tt5c2_CU tt5c3_CU tt5c4_CU tt5d1
5t1_CU tt5t2_CU tt5t3_CU tt5t4_CU tt6_CU utt6_CU
6c3_CU tt6c4_CU tt6d1_CU tt6a1_CU tt6u1_CU tt6t1
6t4_CU tt7_CU utt7_CU tt7c1_CU tt7c2_CU tt7c3_CU
7a1_CU tt7u1_CU tt7t1_CU tt7t2_CU tt7t3_CU tt7t4
#!/bin/bash
OUT="GATE1"
COUNT="14"
DATA="CU4 CU2 CU9var CU3 CU1 CU11admin CU10opt not_sy CU_doonce cutttCU clocal_CU global_CU tivoli_CU"
while [[ -n $DATA ]]
do
printf "%-20s %-5s %-20s \n" "${OUT}" "${COUNT}" "${DATA:0:48}"
OUT=" "
COUNT=" "
DATA="${DATA:48}"
done
能否请您尝试以下。
your_command | awk '
/GATE/{
val=index([=10=],)
while(++i<val){
space=space OFS
}
}
!/^GATE/{
[=10=]=space [=10=]
}
1'
一个班轮:
your_command | awk '/GATE/{val=index([=11=],);while(++i<val){space=space OFS}} !/^GATE/{[=11=]=space [=11=]} 1'
或者按照 Ed 先生的评论尝试以下操作:
your_command | awk '
/GATE/{
space=sprintf("%*s",index([=12=],),"")
}
!/^GATE/{
[=12=]=space [=12=]
}
1'
您使用以下行来打印您的行:
$ printf "%-20s %-5s %-20s \n" "${OUT}" "${COUNT}" "${DATA}"
您遇到的问题是 ${DATA}
包含换行符。我们可以推断出这一点,因为您试图在 20 个字符宽的字段中打印一个超过 20 个字符的字符串(您的格式显示了这一点)。正是这些换行符确保您的 DATA 在下一行的开头继续。如果你想对齐它们,你必须在那个变量中替换你的换行符。
示例:
$ p=$'foo\nbar'
$ printf "%-2s %1s\n" "a" "$p"
a foo
bar
$ printf "%-2s %1s\n" "a" "${p//$'\n'/$'\n' }"
a foo
bar
你知道 DATA 列必须从第 28 个字符开始。所以它前面有 27 个字符 (20+1+5+1)。所以你需要做的就是:
$ printf "%-20s %-5s %-20s \n" "${OUT}" "${COUNT}" "${DATA//$'\n'/$'\n'$(printf "%27s" "")}"
这应该适用于 bash 或现代 ksh。如果您没有这个,并且变量替换确实识别 ${var//str/repl}
,那么您可以使用 awk
:
快速对该单行进行后处理
$ printf "%-20s %-5s %-20s \n" "${OUT}" "${COUNT}" "${DATA}" \
| gawk -v RS= '{gsub(ORS,ORS sprintf("%27s",""))}1'
我有 3 个变量,我使用 printf 来对齐它们的输出 我知道第一个环境变量是一行,所以第二个变量也是 第三个变量的问题是这个变量有巨大的输出因此我想列出它们对齐(我希望下面会清除我的问题)
** 我没有列命令 **
我正在使用
printf "%-20s %-5s %-20s \n" "${OUT}" "${COUNT}" "${DATA}"
OUT11 OUT2 OUT3
---------- ----- --------------
GATE1 14 CU4 CU2 CU9var CU3 CU1 CU11admin CU10opt not_sy
CU_doonce cutttCU clocal_CU global_CU tivoli_CU
GATE2 70 gdba_CU cdba_CU vudb_CU tti1_CU tti3_CU tt3_CU
3c2_CU tt3c3_CU tt3c4_CU tt3d1_CU tt3a1_CU tt3u1
3t3_CU tt3t4_CU tt4_CU utt4_CU tt4c1_CU tt4c2_CU
4d1_CU tt4a1_CU tt4u1_CU tt4t1_CU tt4t2_CU tt4t3
tt5_CU tt5c1_CU tt5c2_CU tt5c3_CU tt5c4_CU tt5d1
5t1_CU tt5t2_CU tt5t3_CU tt5t4_CU tt6_CU utt6_CU
6c3_CU tt6c4_CU tt6d1_CU tt6a1_CU tt6u1_CU tt6t1
6t4_CU tt7_CU utt7_CU tt7c1_CU tt7c2_CU tt7c3_CU
7a1_CU tt7u1_CU tt7t1_CU tt7t2_CU tt7t3_CU tt7t4
我需要它们:
OUT11 OUT2 OUT3
---------- ----- --------------
GATE1 14 CU4 CU2 CU9var CU3 CU1 CU11admin CU10opt not_sy
CU_doonce cutttCU clocal_CU global_CU tivoli_CU
GATE2 70 gdba_CU cdba_CU vudb_CU tti1_CU tti3_CU tt3_CU
3c2_CU tt3c3_CU tt3c4_CU tt3d1_CU tt3a1_CU tt3u1
3t3_CU tt3t4_CU tt4_CU utt4_CU tt4c1_CU tt4c2_CU
4d1_CU tt4a1_CU tt4u1_CU tt4t1_CU tt4t2_CU tt4t3
tt5_CU tt5c1_CU tt5c2_CU tt5c3_CU tt5c4_CU tt5d1
5t1_CU tt5t2_CU tt5t3_CU tt5t4_CU tt6_CU utt6_CU
6c3_CU tt6c4_CU tt6d1_CU tt6a1_CU tt6u1_CU tt6t1
6t4_CU tt7_CU utt7_CU tt7c1_CU tt7c2_CU tt7c3_CU
7a1_CU tt7u1_CU tt7t1_CU tt7t2_CU tt7t3_CU tt7t4
#!/bin/bash
OUT="GATE1"
COUNT="14"
DATA="CU4 CU2 CU9var CU3 CU1 CU11admin CU10opt not_sy CU_doonce cutttCU clocal_CU global_CU tivoli_CU"
while [[ -n $DATA ]]
do
printf "%-20s %-5s %-20s \n" "${OUT}" "${COUNT}" "${DATA:0:48}"
OUT=" "
COUNT=" "
DATA="${DATA:48}"
done
能否请您尝试以下。
your_command | awk '
/GATE/{
val=index([=10=],)
while(++i<val){
space=space OFS
}
}
!/^GATE/{
[=10=]=space [=10=]
}
1'
一个班轮:
your_command | awk '/GATE/{val=index([=11=],);while(++i<val){space=space OFS}} !/^GATE/{[=11=]=space [=11=]} 1'
或者按照 Ed 先生的评论尝试以下操作:
your_command | awk '
/GATE/{
space=sprintf("%*s",index([=12=],),"")
}
!/^GATE/{
[=12=]=space [=12=]
}
1'
您使用以下行来打印您的行:
$ printf "%-20s %-5s %-20s \n" "${OUT}" "${COUNT}" "${DATA}"
您遇到的问题是 ${DATA}
包含换行符。我们可以推断出这一点,因为您试图在 20 个字符宽的字段中打印一个超过 20 个字符的字符串(您的格式显示了这一点)。正是这些换行符确保您的 DATA 在下一行的开头继续。如果你想对齐它们,你必须在那个变量中替换你的换行符。
示例:
$ p=$'foo\nbar'
$ printf "%-2s %1s\n" "a" "$p"
a foo
bar
$ printf "%-2s %1s\n" "a" "${p//$'\n'/$'\n' }"
a foo
bar
你知道 DATA 列必须从第 28 个字符开始。所以它前面有 27 个字符 (20+1+5+1)。所以你需要做的就是:
$ printf "%-20s %-5s %-20s \n" "${OUT}" "${COUNT}" "${DATA//$'\n'/$'\n'$(printf "%27s" "")}"
这应该适用于 bash 或现代 ksh。如果您没有这个,并且变量替换确实识别 ${var//str/repl}
,那么您可以使用 awk
:
$ printf "%-20s %-5s %-20s \n" "${OUT}" "${COUNT}" "${DATA}" \
| gawk -v RS= '{gsub(ORS,ORS sprintf("%27s",""))}1'