如何使用 sed 或 awk 对齐第一次出现的符号

How to use sed or awk to align the first occurrence of a symbol

我在表格上有几行

hello world#it#is#a#nice#day
once upon a time...
yes#and#no
good#bye

我想对齐第一个 #字符(如果有的话)。如果我这样做

$ sed 's/#/\t#/1'

在第一个 #:

之前插入一个制表符
hello world     #it#is#a#nice#day
once upon a time...
yes     #and#no
good    #bye

不是很好!我希望输出更像:

hello world     #it#is#a#nice#day
once upon a time...
yes             #and#no
good            #bye

我想在 bash 中使用 sed 或 awk 实现此目的,但不知道如何实现。

指定同一个输入文件两次,并在第一轮计算最大宽度。一个常见的 Awk 习惯用法是 NR==FNR,当您处理一组文件中的第一个文件时,它是正确的(总行号等于该文件中的行号)。

awk -F '#' 'NR==FNR { if (NR==1 || length() > max) max=length(); next }
    { printf "%*s%s\n", -max, , substr([=10=], length()+1) }' file file

printf 宽度说明符中使用 * 可能不容易 google -- 它说从下一个参数读取宽度(在处理过程中消耗参数格式字符串)。负宽度是左对齐的(正宽度会让你右对齐 space 填充)。

我会欺骗 column 实用程序来执行此操作。您需要一个不在文本中的字符作为标记。我将使用 \x01(二进制 1,ASCII 中的 "start of header")和 bash shell 扩展名 ($'' strings) 来完成这项工作,但任何字符都有效只要它不在输入数据中。

然后:

sed 's/#/\x01#/' filename | column -t -s $'\x01'

这将首先将标记放在第一个 # 之前,然后使用 \x01 作为分隔符对数据进行分栏。