awk 从列的末尾删除一些空格

  • 本文关键字:删除 空格 awk awk gsub
  • 更新时间 :
  • 英文 :


我正在尝试使用以下命令从文件的第二列末尾删除 2 个空格:

awk '{gsub(/[ $]/, "", $2); print}' Myfile

我的输入文件的格式如下所示(此处的字符和数字仅用于显示格式):

1AA       A      1   9.999   9.999   9.999
111BB       B   1111   9.999   9.999   9.999
1111AABB  ABCD  11111   9.999   9.999   9.999

我想要如下输出:

1AA       A    1   9.999   9.999   9.999
111BB       B 1111   9.999   9.999   9.999
1111AABB  ABCD11111   9.999   9.999   9.999

实际上,第三列将 2 个空格移向第二列。

但是我的代码没有:(

谁能向我解释我的代码有什么问题?

提前谢谢你!

在每个 Unix 盒子上使用任何 shell 中的任何 awk:

$ awk '{print substr($0,1,14) substr($0,17)}' file
1AA       A    1   9.999   9.999   9.999
111BB       B 1111   9.999   9.999   9.999
1111AABB  ABCD11111   9.999   9.999   9.999

或者使用 GNU awk 表示 FIELDWIDTHS(如果您有一个较旧的 gawk 版本,它不理解*的意思是"行的其余部分",请使用9999或其他一些大数字代替*):

$ awk -v FIELDWIDTHS='14 2 *' '{print $1 $3}' file
1AA       A    1   9.999   9.999   9.999
111BB       B 1111   9.999   9.999   9.999
1111AABB  ABCD11111   9.999   9.999   9.999

您的代码的问题在于您尝试从 $2 中删除 2 个空格,但您的字段是空格分隔的,因此任何字段中都没有空格,包括 $2,空格位于字段之间。此外,您的正则表达式/[ $]/的意思是"空白或文字$ char",而不是我相信您认为的"字符串末尾之前的 2 个空格"。

在这里,在 gsubawk内部,[ $]模式匹配两个字符之一:空格或$字符,等于[$ ]

由于您的文件是固定宽度的,因此您可以使用 GNU awk 命令,例如

awk 'BEGIN { FIELDWIDTHS="10 6 8 8 8 8" } {gsub(/  $/,"",$2); print $1 $2 $3 $4 $5 $6}' Myfile > newMyfile

其中/ $/匹配输入末尾的两个文本空格($定义字符串的末尾)。

有关FIELDWIDTHS的更多信息,请参阅手册"4.6.1 处理固定宽度数据gawk手册。

使用您显示的示例,请尝试遵循rev+awk+rev组合代码。用 GNUawk编写和测试。

rev Input_file | 
awk '
match($0,/^S+(s+S+){3}/){
val1=substr($0,RSTART,RLENGTH)
val2=substr($0,RSTART+RLENGTH)
sub(/^  /,"",val2)
$0=val1 val2
}
1
' | rev

对于显示的示例,输出将如下所示:

1AA       A    1   9.999   9.999   9.999
111BB       B 1111   9.999   9.999   9.999
1111AABB  ABCD11111   9.999   9.999   9.999

说明以下是上述代码的详细级别说明。

rev Input_file |                    ##using rev on Input_file to get output in reverse order.
awk '                               ##Sending rev output as standard input to awk.
match($0,/^S+(s+S+){3}/){      ##using match function of awk to match regex ^S+(s+S+){3}
val1=substr($0,RSTART,RLENGTH)  ##Creating val1 variable which has matched values in it.
val2=substr($0,RSTART+RLENGTH)  ##Creating val2 variable which has rest of values(after matched value).
sub(/^  /,"",val2)              ##Substituting starting 2 spaces(which are actually 2 spaces we need to remove between 2nd and 3rd field in question) with NULL in val2 here.
$0=val1 val2                    ##Assigning val1 and val2 values to current line.
}
1                                   ##printing current line here.
' | rev                             ##Sending awk program output to rev to print values in actual order.

最新更新