如何使用 awk 命令清空第 n 到 m 个字段?

如何使用 awk 命令清空第 n 到 m 个字段?

我想使用 AWK 解决以下问题。

如果使用 sed 或 Perl 等语言可以实现任何其他解决方案,我们也将不胜感激。

以下是输入:

U,N,UNIX,000,A,5
N,P,SHELL,111,B,6
I,M,UNIX,222,C,7
X,Y,BASH,333,D,8
P,R,SCRIPT,444,E,9

我想要的输出如下:

U,N,,,A,5
N,P,,,B,6
I,M,,,C,7
X,Y,,,D,8
P,R,,,E,9

另请注意:我不知道每行的字段总数。我只知道字段3和4要留空。

答案1

要按比例空白命令中从第 n 个到第 m 个的所有字段awk,您不应该对这些值进行硬编码;你应该使用“for”循环:

awk 'BEGIN { FS = ","; OFS = ","} {for (i = 3; i <= 4; i++) { $i = "" }; print}' inputfile

如果您想清空不同的范围,请调整上述代码中的值“3”和“4”。


解释:

BEGIN { ... }在查看文件的任何行之前先处理该块。

OFS设置输出字段分隔符,并FS设置输入字段分隔符。我们希望它们都是逗号。

循环for就像 C 语法一样。在这种情况下,它对as 3 和 as 4执行以下操作{ code block }i

值得$i一提的是,它与 shell 语法完全不同。在 shell 脚本中,变量名必须以 为前缀才能$扩展为变量的值。在awk.在 中awki本身扩展为它的值(在本例中为 3 或 4),并且$后面跟着一个数字表示场地在那个编号的位置。因此将第 th 字段$i = ""设置i为空字符串。

然后print,不带参数的命令默认打印整行。实际上,它获取由 分隔的行中的所有字段以及由任何先前命令修改的行,并将它们全部打印出来,并在末尾用换行符FS分隔并后跟换行符。OFS


等效的较短命令:

我觉得如果您要将上面的命令包含在脚本中,它是最干净且最容易扩展的。它非常明确地说明了它正在做什么并且非常可读。另外,整个事情可以分解为一个独立的awk脚本而无需更改;使用-v-F切换到您的调用时无法自动完成的事情awk。 (当然,这并不是不使用它们的理由。只是需要注意一些事情。)

特别是对于一次性使用,我将使用以下内容:

awk -F, -v OFS=, '{for (i = 3; i <= 4; i++) { $i = "" }; print}' inputfile

开关-F设置 的值FS。该开关允许您在命令行上-v设置变量的值。awk

更一般地说,该开关对于将 shell 变量作为 awk 变量传递:以及更改使用命令行选项从脚本文件中提取的独立脚本的运行时-v行为非常有用。-v myawkvar="$myshellvar"awk-f scriptname

答案2

</path/to/in_file awk -v 'FS=,' -v 'OFS=,' '{$3=$4=""; print}'

解释

  • </path/to/in_file:读取文件到标准中。
  • -v 'FS=,' -v 'OFS=,':将文件分隔符和输出文件分隔符设置为,.
  • '{$3=$4=""; print}':将第三个和第四个字段设置为空白,然后打印整行(缩写形式由杰森·瑞恩)。

答案3

sed 's/\([^,]*,\)\{2\}/,,/2' <in >out

U,N,,,A,5
N,P,,,B,6
I,M,,,C,7
X,Y,,,D,8
P,R,,,E,9

这会将第二次出现的一组两个连续的逗号分隔字段替换为两个逗号。

你也可以这样做:

sed 's/[^,]*//4;s///3' <in >out

...它将任何 num 个非逗号字符序列的第四次和第三次出现替换为空。

像 @Wildcard 那样做 - 使用可扩展的循环:

sed -e:t -e'/\n\{2\}/!s/\(\n*\)[^,]*./\n\1/3;/\n$/!tt' -e's///;y/\n/,/'

...或者...

sed -e:t -e's/\n$//;s/\n/&/2;to'  \
    -e's/\(\n*\)[^,]*./\1\n/3;tt' \
    -e:o -ey/\\n/,/

...在哪里3是您要开始消隐的字段编号,,是分隔符,并且2是您要全部空白的字段数。

不管你怎么写...

sed "$script" <<""
U
N,P
I,M,UNIX
X,Y,BASH,333
P,R,SCRIPT,444,E,9

U
N,P
I,M,
X,Y,,
P,R,,,E,9

...尽管您可能需要使用文字换行符来代替nin .../\1\n/3

答案4

我会用perl

perl -F, -lane '@F[2,3]=""; print join ",", @F'

这使用-a自动分割,并使用-F逗号作为字段分隔符。-n按行迭代 STDIN。然后-e指定一个脚本来替换字段 2 和 3(perl 从零开始)并打印结果。

-l隐式删除和添加行结尾。

相关内容