如何使用AWK右键填充带有空格的字段

如何使用AWK右键填充带有空格的字段,awk,Awk,我有一个文件,我正试图从使用AWK中删除客户名称。 该文件是一个固定宽度的文件,每一列都有意义 该文件由许多行组成,格式相同,非常类似于以下内容: 1234-123 123456 12345678901234CUSTOMER NAME TO REMOVE12345-1234 TRN 123-123 12345678901-1234 TRN 12345678 1234-123 123456 12345678901234CUSTOMER NAME TO REMOVE

我有一个文件,我正试图从使用AWK中删除客户名称。 该文件是一个固定宽度的文件,每一列都有意义

该文件由许多行组成,格式相同,非常类似于以下内容:

1234-123   123456 12345678901234CUSTOMER NAME TO REMOVE12345-1234 TRN   123-123   12345678901-1234  TRN 12345678        
1234-123   123456 12345678901234CUSTOMER NAME TO REMOVE12345-1234 TRN   123-123   12345678901-1234  TRN 12345678        
1234-123   123456 12345678901234CUSTOMER NAME TO REMOVE12345-1234 TRN   123-123   12345678901-1234  TRN 12345678        
1234-123   123456 12345678901234CUSTOMER NAME TO REMOVE12345-1234 TRN   123-123   12345678901-1234  TRN 12345678
我需要用一个假想的名称替换客户名称,以便所需的输出为:

1234-123   123456 12345678901234SENTINAL PRIME         12345-1234 TRN   123-123   12345678901-1234  TRN 12345678        
1234-123   123456 12345678901234OPTIMUS PRIME          12345-1234 TRN   123-123   12345678901-1234  TRN 12345678        
1234-123   123456 12345678901234BUMBLE BEE             12345-1234 TRN   123-123   12345678901-1234  TRN 12345678        
1234-123   123456 12345678901234IRON HIDE              12345-1234 TRN   123-123   12345678901-1234  TRN 12345678
我有一个用于此目的的变压器名称列表,存储在名为
transformer.names
的文件中

SENTINEL PRIME
OPTIMUS PRIME
BUMBLEBEE
IRONHIDE
但是,为了使原始文件的每一行保持相同的宽度,我需要用空格右键填充转换器名称,因为我拥有的转换器名称的长度都不同

似乎可以使用AWK将这些名称右键填充到一定的长度,但我还没有设法弄明白(或找到足够清楚的答案),让我无法理解

下面是我当前的AWK脚本

#!/usr/bin/awk -f
BEGIN {
}
{
  getline line < "transformer.names"
  print substr($0, 0, 30) line substr($0, 62, 120)
}
我想我可以包括一行这样的东西在上面的打印行的地方,但我还没有设法让它工作

printf "-%32s|", substr($0, 0, 30) line substr($0, 62, 120)

任何提示都会很棒

请您尝试以下内容,并让我知道这是否对您有帮助。所以它将拥有所有的转换器名称,假设它的值小于输入文件行,那么它将保持打印行从它开始

awk '
FNR==NR{
  a[FNR]=$0;
  count=FNR;
  next}
{
  val=val==count?1:++val;
  print substr($0,1,32) a[val]"\t\t"substr($0,56)
}' transformer.names  Input_file
解释:现在也为上述代码添加解释

awk '
FNR==NR{                                          ##Checking condition here FNR==NR which will be TRUE when first Input_file is being read.
  a[FNR]=$0;                                      ##Creating an array named a whose index is FNR and value is current line.
  count=FNR;                                      ##Creating variable count whose value is FNR value(current line number value of first Input_file).
  next}                                           ##next will skip further statements from here onward.
{                                                 ##This block will execute when 2nd Input_file is being read.
  val=val==count?1:++val;                         ##Creating variable val whose value is increment each time and when it is equal to count it is set to 1 then.
  print substr($0,1,32) a[val]"\t\t"substr($0,56) ##Printing sub-string from 1 to 32 chars, value of a[val] TABs then sub-string from 56 char to till last of line.
}' transformer.names  Input_file                  ##Mentioning Input_file(s) name here.

您需要将
%Ns
应用于要填充整行的特定字段,并且需要将减号(对于leftpad/righalign)作为说明符的一部分,而且
printf
不会像
print
那样自动添加行/记录分隔符,因此您需要添加以下内容:

 printf "%s%-32s%s\n", substr($0, 1, 30), newname, substr($0, 62, 120)
 # note commas; this is a format string containing three specifiers, 
 # and separate three data values used for those three specifiers
或者,您可以填充字段,然后连接:

 print substr($0,1,30) sprintf("%-32s", newname) substr($0,62,120) 
 # no commas except within the sprintf (and the substr's) 
如果数据文件的行数比“transformernames”文件的行数多,那么您需要缓冲这些名称,并重复遍历它们,如Ravinder所示

此外,awk中的
substr
位置从1开始;如果指定0或负数,它将被视为1,但我认为更清楚地表达你的意思,所以我修正了它。在您发布的示例数据中,62不是客户名称后零件的正确起始位置,但您说数据与真实数据“非常相似”,因此我不知道56或62或其他内容是否正确。

#/usr/bin/awk-f
#!/usr/bin/awk -f
BEGIN {
}
{
  getline line < "transformer.names"
  printf("%s %-32s %s \n", substr($0, 0, 30), line, substr($0, 62, 120))
}
开始{ } { getline行<“变压器名称” printf(“%s%-32s%s\n”),子字符串($0,0,30),行,子字符串($0,62,120)) }

你的问题基本上已经有了答案!我只是复制了您的数据并对其进行了一些修改:)

您的数据在要修改的文本之前似乎不是大写字母。
所以你可以试试这个awk

awk '
FNR==NR {
  a[NR]=$0
  b=length()
  len = len < b ? b : len
  next
}
{
  c = sprintf( "%-*2$s" , a[FNR], (len+1))
  sub(/[A-Z][A-Z ]+/,c)
}
1' transformer_name customer_name
awk'
FNR==NR{
a[NR]=$0
b=长度()
len=len

首先,我们将所有变压器名称放入数组a中,并将较大的长度保留在len中 在我们用新名称替换所有旧名称后,调整c中的格式。

您可以根据您的需要修改(len+1)。

请您提供更多的输入样本,这将有助于我们帮助您。完成。干杯:)谢谢你,我一定会的!你能描述代码的关键部分是如何工作的吗?对于刚进入这个领域的人来说,这是不直观的。@JohnDeverall,只是这样做了:)现在请检查我的解释,也可以查看一下这个链接。选项卡只在一些输出设备上起作用,并且当字段结束列是8的倍数,并且替换值的长度变化不超过7时。对不起,这是误导。我在问题中修正了它。
awk '
FNR==NR {
  a[NR]=$0
  b=length()
  len = len < b ? b : len
  next
}
{
  c = sprintf( "%-*2$s" , a[FNR], (len+1))
  sub(/[A-Z][A-Z ]+/,c)
}
1' transformer_name customer_name