如何对齐具有多行的第 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'