Bash 如何对齐具有多行的第n列

Bash 如何对齐具有多行的第n列,bash,awk,ksh,aix,Bash,Awk,Ksh,Aix,我有3个变量,我使用printf来对齐它们的输出 我知道第一个环境变量是一行,所以第二个变量也是 第三个变量的问题是这个变量有巨大的输出,因此我想把它们列出来(我希望下面能澄清我的问题) **我没有列命令** 我正在使用 printf“%-20s%-5s%-20s\n”“${OUT}”“${COUNT}”“${DATA}” 我需要它们: OUT11 OUT2 OUT3 ---------- ----- -------------- GATE

我有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

#/bin/bash
OUT=“GATE1”
COUNT=“14”
DATA=“CU4 CU2 CU9var CU3 CU1 CU11管理CU10选择非系统CU\u doonce CU clocal\u CU global\u CU tivoli\u CU”
而[[-n$DATA]]
做
printf“%-20s%-5s%-20s\n”“${OUT}”“${COUNT}”“${DATA:0:48}”
OUT=“”
COUNT=“”
DATA=“${DATA:48}”
完成
#/bin/bash
OUT=“GATE1”
COUNT=“14”
DATA=“CU4 CU2 CU9var CU3 CU1 CU11管理CU10选择非系统CU\u doonce CU clocal\u CU global\u CU tivoli\u CU”
而[[-n$DATA]]
做
printf“%-20s%-5s%-20s\n”“${OUT}”“${COUNT}”“${DATA:0:48}”
OUT=“”
COUNT=“”
DATA=“${DATA:48}”
完成

请尝试以下内容

your_command | awk '
/GATE/{
  val=index($0,$3)
  while(++i<val){
    space=space OFS
  }
}
!/^GATE/{
  $0=space $0
}
1'

你能试试下面的吗

your_command | awk '
/GATE/{
  val=index($0,$3)
  while(++i<val){
    space=space OFS
  }
}
!/^GATE/{
  $0=space $0
}
1'

您可以使用以下行打印您的行:

$ printf "%-20s %-5s %-20s \n" "${OUT}" "${COUNT}" "${DATA}"
您遇到的问题是
${DATA}
包含换行符。我们可以推断这一点,因为您试图在20个字符宽的字段中打印长度超过20个字符的字符串(您的格式显示了这一点)。正是这些换行符确保数据在下一行的开头继续。如果要对齐它们,必须在该变量中对新行进行一个小的替换

例如:

$ p=$'foo\nbar'
$ printf "%-2s %1s\n" "a" "$p"
a  foo
bar
$ printf "%-2s %1s\n" "a" "${p//$'\n'/$'\n'   }"
a  foo
   bar
您知道数据列必须从字符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'

您可以使用以下行打印您的行:

$ printf "%-20s %-5s %-20s \n" "${OUT}" "${COUNT}" "${DATA}"
您遇到的问题是
${DATA}
包含换行符。我们可以推断这一点,因为您试图在20个字符宽的字段中打印长度超过20个字符的字符串(您的格式显示了这一点)。正是这些换行符确保数据在下一行的开头继续。如果要对齐它们,必须在该变量中对新行进行一个小的替换

例如:

$ p=$'foo\nbar'
$ printf "%-2s %1s\n" "a" "$p"
a  foo
bar
$ printf "%-2s %1s\n" "a" "${p//$'\n'/$'\n'   }"
a  foo
   bar
您知道数据列必须从字符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'


“${DATA:0:48}”:0403-011指定的替换对该命令无效。@mshafey是否在以脚本形式运行我上面编写的内容时出错?如果是这样的话,Bash的版本是什么?当然可以——我曾经看到aix上的Bash和linuxOk之间的差异,也许可以使用正则表达式:
if[[“$data=~^(.{48,48})(..*$])];然后
printnow=“${Bash_REMATCH[1]}”
data=“${Bash_REMATCH[2]}”
data=
fi
请注意,OP正在AIX系统上运行,可能是旧版本的KSH。第一条注释中的错误似乎指向“${DATA:0:48}”:0403-011指定的替换对该命令无效。@mshafey是否在以脚本形式运行上面编写的内容时发生错误?如果是这样的话,Bash的版本是什么?当然可以——我曾经看到aix上的Bash和linuxOk之间的差异,也许可以使用正则表达式:
if[[“$data=~^(.{48,48})(..*$])];然后
printnow=“${Bash_REMATCH[1]}”
data=“${Bash_REMATCH[2]}”
data=
fi
请注意,OP正在AIX系统上运行,可能是旧版本的KSH。第一条注释中的错误似乎指向了这一点。我不知道如何在我的printf中使用您的代码line@mshafey,您不需要在printf中使用它,只需使用您的输入文件运行代码,看看会发生什么。@mshafey,用
echo$OUT$COUNT$DATA
管道将您的循环传递到itI,并在awk上方传递,但它给出了完全相同的结果
val=index($0,$3);而(++我不知道如何在我的printf中使用你的代码line@mshafey,您不需要在printf中使用它,只需使用您的输入文件运行代码,看看会发生什么。@mshafey,使用
echo$OUT$COUNT$DATA
将您的循环输送到itI,itI在awk上方传递,但它给出了完全相同的结果
val=index($0,$3);而(++i./cld3[11]:“”${fs/$“\\n”/$“\\n”$(printf“%27s”“”)}”“:0403-011指定的替换对该命令无效。@mshafey似乎有两个反斜杠。我使用了$printf“%-20s%-5s%-20s\n”“${OUT}”“${COUNT}”“${DATA/$'\n'/$\n'/$(printf“%27s”“”)}”它给出的错误为>>>。/cld3[11]:“${fs/$/$\n/$\n/$”\printf 27s''}”:0403-011指定的替换对该命令无效。@mshafey您使用的是哪个shell和哪个系统?/cld3[11]:“${fs/$”\\n”/$“\\n”$(printf“%27s”)}”“:0403-011指定的替换对该命令无效。@mshafey似乎有两个反斜杠。我使用了$printf”%-20s%-5s%-20s\n“${OUT}”“${COUNT}”${DATA/$'\n'/$'\n'$(printf“%27s”“”)}“它给出的错误为>>>。/cld3[11]:“${fs/$\n/$\n$(printf“%27s”“”)}”:0403-011指定的替换对该命令无效。@mshafey您使用的是哪个shell以及哪个系统?使用名称为OUT COUNT和DATA的shell变量并试图以这种方式打印它们意味着您已经偏离了轨道,试图使用shell脚本来做一些shell不打算做的事情,即text proc埃辛·波