如何根据字段长度添加尾随空格

如何根据字段长度添加尾随空格

我想在每个字段中添加尾随空格。我的文件看起来像:

输入文件:

A|B|C|D

输出文件中字段 1 的长度为:1

输出文件中字段 2 的长度为:3

输出文件中的字段 3 长度为:4

输出文件中的字段 4 长度为:6

期望的输出:

AB  C   D  

如何在shell中实现这一点?请协助

答案1

awk

awk -F'|' '{printf "%-1.1s%-3.3s%-4.4s%-6.6s\n", $1, $2, $3, $4}' < input > output

会做正确的空间填充和截断。

根据awk实现的不同,该长度将以字节或字符为单位(对于多字节字符会有所不同)。在任何情况下,都不基于这些字符的显示宽度(例如双宽或 0 宽度字符,或在终端上显示宽度不为 1 的 TAB)。

例子:

$ echo 'A|B|C|D' | awk -F'|' '{printf "%-1.1s%-3.3s%-4.4s%-6.6s\n", $1, $2, $3, $4}'
AB  C   D

(所有这些 A B C D字素均由一个字符组成,在任何语言环境中每个字素均由一个字节组成,并且每个字素都是单宽度的)。

$ echo 'A|B|Ç|D' | gawk -F'|' '{printf "%-1.1s%-3.3s%-4.4s%-6.6s\n", $1, $2, $3, $4}'
AB  Ç   D
$ echo 'A|B|Ç|D' | mawk -F'|' '{printf "%-1.1s%-3.3s%-4.4s%-6.6s\n", $1, $2, $3, $4}'
AB  Ç  D

Ç( UTF-8 中的2 字节、1 宽度字符)

$ echo $'A|B|C\u0327|D' | gawk -F'|' '{printf "%-1.1s%-3.3s%-4.4s%-6.6s\n", $1, $2, $3, $4}'
AB  Ç  D
$ echo $'A|B|C\u0327|D' | mawk -F'|' '{printf "%-1.1s%-3.3s%-4.4s%-6.6s\n", $1, $2, $3, $4}'
AB  Ç D

1 字节、1 宽度C与 0 宽度、2 字节(UTF-8 格式)组合,组合变音符号以形成 1 宽度、2 个字符、3 字节Ç字形,即预组合 U+00C7 的分解版本Ç上一个示例中的字符。

要考虑字符的显示宽度,使用某些expand实现(尽管不是 GNU expand)并假设输入不包含 TAB 字符并且没​​有一个输入字段首先超过其分配的宽度,您可以这样做:

<input sed $'s/|/|\t/g;s/$/|\t/' | expand -t3,8,14,22 | sed 's/| //g' >output

的输出printf '%s\n' 'A|B|C|D' $'A|B|\uc7|D' $'A|B|C\u327|D'应该给出:

AB  C   D
AB  Ç   D
AB  Ç   D

答案2

仅使用bashshell 功能...

对于提供的样本数据:

$ foo="A|B|C|D"; printf "%s%s  %s   %s     \n" $(echo -e "${foo//|/ }" )
AB  C   D     

$ foo="A|B|C\u0327|D"; printf "%s%s  %s   %s     \n" $(echo -e "${foo//|/ }" )
AB  Ç   D     

对于每个问题的固定字段输出,假设没有输入字段超过其最大指定宽度:

$ foo="A|B|C|D"; printf "%-1.1s%-3.3s%-4.4s%-6.6s\n" $(echo -e "${foo//|/ }" )
AB  C   D     

对于诸如 之类的多字节字符,您会遇到这样的问题: ( shell 内置和独立实用程序)中的宽度说明符计算的是字节,而不是多字节字符。因此,您可能会得到“意外”的输出。printfbash

$ foo="A|B|\uc7|D"; /bin/printf "%-1.1s%-3.3s%-4.4s%-6.6s\n" $(echo -e  "${foo//|/ }" )
AB  Ç  D    

$ foo="A|B|\uc7|D"; /bin/printf "%-1.1s%-3.3s%-4.4s%-6.6s\n" $(echo -e  "${foo//|/ }" ) | xxd
00000000: 4142 2020 c387 2020 4420 2020 2020 0a    AB  ..  D     .
$ 
 

相关内容