我有一个文本文件foo.txt
,其中包含带有标点符号的单词。
我想做的是使用awk
过滤每个标点符号,所以我使用了正则表达式作为字段分隔符,例如awk -F '[^a-zA-Z]+' '{ print $0 }' foo.txt
,我面临的问题是文本保持不变像原始的一样,没有任何东西被过滤。
有人知道为什么会这样吗?
输入
¿Hello? How... are foo you?'
Bye ,, hehe '" .lol
预期结果
Hello How are foo you
Bye hehe lol
P.D
我知道使用sed 's/[[:punct:]]//g' foo.txt
或sed s/[^A-Za-z]/" "/g foo.txt
之类的sed可以达到相同的结果,但是我想知道为什么awk
命令不起作用,我已经在各处进行了调查,并且我找不到答案,我无法入睡。
答案 0 :(得分:1)
如果您想知道在哪里可以找到其背后的规则,我想指出Awk POSIX standard:
但是,您必须在两个位置找到答案:
描述
awk实用程序应将每个输入记录解释为字段序列,默认情况下,字段是非
非 字符的字符串。可以使用内置 FS
变量或-F
sepstring选项来更改默认的和 字段定界符。 awk实用程序应表示记录 $1
中的第一个字段,第二个$2
,以此类推。 符号$0
代表整个记录;设置其他任何字段都会导致重新评估$0
。分配给$0
将重置所有其他字段的值和NF
内置变量。变量和特殊变量
对不存在的字段(即
$NF
之后的字段)的引用应评估为未初始化的值。此类引用不得创建新字段。但是,分配给不存在的字段(例如$(NF+2)=5
)将增加NF
的值;用未初始化的值创建任何中间字段;并且导致$0
的值被重新计算,其中各字段之间的间隔为OFS
。每个字段变量在创建时应具有字符串值或未初始化的值。使用$0
从FS
创建的字段变量应具有未初始化的值,并且该变量不包含任何字符。
在引入新字段时,找到重新计算awk
的规则有点$0
,但这实际上是规则。
此外,语句print $0
打印整个字段。因此,根据以上所述,您首先需要重新计算$0
,如@oguzismail的答案所示。
因此,可以通过以下方式更改字段分隔符:
awk 'BEGIN{FS="oldFS"; OFS="newFS"}{$1=$1}1' <file>
备注: ,您无需检查该行是否包含任何NF{$1=$1}
字段,因为{$1=$1}
只会引入一个空字段而不会额外的OFS
。