我正在尝试使用以下命令从文件的第二列末尾删除 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.