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

Tom*_*man 13 command-line text-processing

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

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

前:

123@example.com
456789@example.net
01234@something-else.com
Run Code Online (Sandbox Code Playgroud)

后:

   123@example.com
456789@example.net
 01234@something-else.com
Run Code Online (Sandbox Code Playgroud)

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

ste*_*ver 11

在最简单的情况下,您可以在适当大的字段宽度中打印第一个字段,例如

awk -F@ 'BEGIN{OFS=FS} {$1 = sprintf("%12s", $1)} 1' file
         123@example.com
      456789@example.net
       01234@something-else.com
Run Code Online (Sandbox Code Playgroud)

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


Sun*_*eep 6

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/'
     123@example.com
  456789@example.net
   01234@something-else.com
Run Code Online (Sandbox Code Playgroud)


Dav*_*ter 5

一个快速的 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)
Run Code Online (Sandbox Code Playgroud)

用法:

python3 align-field.py < data.txt
Run Code Online (Sandbox Code Playgroud)


wvx*_*xvw 3

没有 awk。仅sedcolumn

column -ts@ file.txt | sed -E 's/([^ ]+)([ ]+) (.+)/\2\1@\3/'
Run Code Online (Sandbox Code Playgroud)

输出:

   123@example.com
456789@example.net
 01234@something-else.com
Run Code Online (Sandbox Code Playgroud)

现在,我想,这与 Sundeep 的解决方案几乎相同,它只是看起来更短/对 的调用更少sed,并且它还假设@每行只发生一次。