如何将列表与特定字符对齐?

如何将列表与特定字符对齐?

是否有一个或一组命令可用于将文本行与任意字符水平对齐?例如,对于电子邮件地址列表,输出将生成一个文本文件,其中所有“@”字符垂直排列。

为了取得成功,我相信必须在大多数行的开头添加可变数量的空格。我不想要单独的专栏,因为它们需要更多的精力来阅读(例如,column -t -s "@" < file.txt)。

前:

[email protected]
[email protected]
[email protected]

后:

   [email protected]
[email protected]
 [email protected]

换句话说:我可以指定一个字符作为锚点,周围的文本围绕该锚点水平居中吗?我的用例是电子邮件地址,以便更容易进行视觉扫描。

答案1

最简单的是,您可以以适当大的字段宽度打印第一个字段,例如

awk -F@ 'BEGIN{OFS=FS} {$1 = sprintf("%12s", $1)} 1' file
         [email protected]
      [email protected]
       [email protected]

据我所知,任何不假设特定最大字段宽度的方法都需要将文件保存在内存中或进行两次传递。

答案2

hacky 解决方案,对输入文本做了很多假设

$ # four commas to reduce chance of it affecting actual email address
$ sed 's/@/,,,,@/' ip.txt | column -t -s,,,,
123     @example.com
456789  @example.net
01234   @something-else.com

$ sed 's/@/,,,,@/' ip.txt | column -t -s,,,, | sed -E 's/^([^ ]+)( +)/\2\1/'
     [email protected]
  [email protected]
   [email protected]

答案3

一个快速的 Python 解决方案,使用尽可能短的填充长度,将分隔符左侧的所有字符串右对齐:

#!/usr/bin/env python3
import sys
fieldsep = '@'
records = [line.rstrip('\n').split(fieldsep, 1) for line in sys.stdin]
col1_len = max((len(r[0]) for r in records), default=0)
for r in records:
    print(r[0].rjust(col1_len), r[1], sep=fieldsep)

用法:

python3 align-field.py < data.txt

答案4

另一个 GNUawk+column解决方案:

awk '{ split($0,a,/ +/,sep); printf "%*s@%s\n",length($1 sep[1])-2,$1,$2 }' <(column -ts'@' file)

输出:

   [email protected]
[email protected]
 [email protected]

相关内容