Text 如何使用sed或awk对齐符号的第一个引用

Text 如何使用sed或awk对齐符号的第一个引用,text,replace,awk,sed,gawk,Text,Replace,Awk,Sed,Gawk,我在表格上有行 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实

我在表格上有行

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
,当您处理多个文件组中的第一个文件时(总行号等于此文件中的行号),这是正确的


printf
宽度说明符中使用
*
对谷歌来说可能并不容易——它表示从下一个参数读取宽度(在处理格式字符串时使用参数)。负宽度是左对齐的(正宽度将使您的空间填充右对齐)。

我会诱使
实用程序这样做。您需要一个不在文本中的字符作为标记。我将使用
\x01
(二进制1,ASCII中的“头的开始”)和bash shell扩展(
$''字符串
)来实现这一点,但任何字符只要不在输入数据中就可以工作

然后:


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

您尝试了什么,以及它是如何失败的?你事先知道最长的输入有多宽吗?我不知道最右边的位置,第一次出现的
#
。这意味着解决方案必须包含两个过程。我的解决方案是一个过度杀戮的Java程序,但我希望在bash中有一个简短而甜美的一行程序。我尝试过谷歌搜索解决方案(没有成功),并且我已经开始学习awk(进行中的工作既慢又耗时),因此我在这里发表文章。插入标签是迄今为止我所做的最好的(使用sed)。(我想你指的是“最左边的”。@tripleee-谢谢,这比我的标签好多了。我需要通过传递这些行,以某种方式提取值“25”。我正在努力解决这个问题。是的,最左边的,不是最右边的!您将要重新加载,您已经有两个答案。但是,一个小细节是,没有
#
-符号的行完整地放在第一列中。我最好只根据至少包含一个
的行对齐
。但是相对较小的细节。嗯……我想你可以按照
sed'/#/!s/^/#\x02/;s/#/\x01#/'filename | column-tns$'\x01'| sed's/^*#\x02/'
,即,将不包含
#
的行移到第二列(通过在
#
前面加上前缀),然后移回到前面。如果行可以以
#
开头,则需要第二个标记字符。一方面,这对文本来说可能不是问题,特别是因为标记在这个特定的上下文中只是一个标记,另一方面,你不想被禁止的字符淹没,所以这种技术不能无限期地扩展。
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
awk -F '#' 'NR==FNR { if (NR==1 || length($1) > max) max=length($1); next }
    { printf "%*s%s\n", -max, $1, substr($0, length($1)+1) }' file file
sed 's/#/\x01#/' filename | column -t -s $'\x01'