使用 sed 或 awk 向右填充带空格的正则表达式

right pad regex with spaces using sed or awk

我有一个文件,其中有两个字段用 : 分隔,两个字段的长度不同,第二个字段可以包含各种字符(用户输入)。我希望第一个字段用空格填充到 15 个字符的固定长度,对于第一个字段我有一个工作正则表达式 @.[A-Z0-9]{4,12}.

示例:

@ABC123:"wild things here"
@7X3Z:"":":@":";:*:-user input:""
@99999X999:"also, imagine: unicode, yay!"

期望的输出:

@ABC123        :"wild things here"
@7X3Z          :"":":@":";:*:-user input:""
@99999X999     :"also, imagine: unicode, yay!"

有很多示例如何对数字进行零填充,但令人惊讶的是,关于常规填充正则表达式或字段的示例并不多,使用(最好)sed 或 awk 有什么帮助吗?

perl:

$ perl -pe 's/^[^:]+/sprintf("%-15s",$&)/e' ip.txt
@ABC123        :"wild things here"
@7X3Z          :"":":@":";:*:-user input:""
@99999X999     :"also, imagine: unicode, yay!"

e 标志允许您在替换部分使用 Perl 代码。 $& 将具有由 sprintf.

格式化的匹配部分

awk:

# should work with any awk
awk 'match([=11=], /^[^:]+/){printf "%-15s%s\n", substr([=11=],1,RLENGTH), substr([=11=],RLENGTH+1)}'

# can be simplified with GNU awk
awk 'match([=11=], /^[^:]+/, m){printf "%-15s%s\n", m[0], substr([=11=],RLENGTH+1)}'
# or
awk 'match([=11=], /^([^:]+)(.+)/, m){printf "%-15s%s\n", m[1], m[2]}'
  • substr([=17=],1,RLENGTH)m[0] 将给出第一个字段的内容。我在这里使用 1 而不是通常的 RSTART 因为我们正在匹配行的开头
  • substr([=21=],RLENGTH+1) 将给出剩余的行内容(即从第一个 :
  • 有关 match 函数的详细信息,请参见 awk manual: String-Manipulation

这是另一个 awk 解决方案,适用于任何版本的 awk:

awk 'BEGIN {FS=OFS=":"} { = sprintf("%-15s", )} 1' file

@ABC123        :"wild things here"
@7X3Z          :"":":@":";:*:-user input:""
@99999X999     :"also, imagine: unicode, yay!"

在此处添加另一种向第一列添加空格的方法,尽管 anubhava 对 sprintf 的回答是更好的答案,但在此处添加是一个选项。在这里,我创建了一个名为 spaces 的变量,可以在其中定义我们需要添加到其中的空格数。

awk -v spaces="15" 'BEGIN{FS=OFS=":"} {sub(/:/,sprintf("%"spaces-length()"s",":"))} 1' Input_file

说明: 为以上添加详细说明。

awk -v spaces="15" '  ##Starting awk program from here, setting spaces to 15 here.
BEGIN{                ##Starting BEGIN section of this program from here.  
  FS=OFS=":"          ##Setting FS and OFS as colon here.
}
{
  sub(/:/,sprintf("%"spaces-length()"s",":")) ##Substituting colon first occurrence with spaces(left padding of spaces) along with colon here.
}
1                     ##Printing current line here.
' Input_file          ##Mentioning Input_file name here.

我相信anbhava

的解决方案
awk 'BEGIN {FS=OFS=":"} { = sprintf("%-15s", )} 1' file

可以进一步简化为:

awk -F: 'BEGIN{FS=OFS} =sprintf("%-15s",)'

{ } 和最后的 1 是可选的