Sorting 是否删除具有特定列长度的行?
我有一个如下所示的文本文件:Sorting 是否删除具有特定列长度的行?,sorting,awk,sed,string-length,Sorting,Awk,Sed,String Length,我有一个如下所示的文本文件: A : 1 Boy : 3 Ahoy! : 7 more : 8 Ahoy! : 7 more : 8 我必须删除长度小于或等于3个字母的行。输出应如下所示: A : 1 Boy : 3 Ahoy! : 7 more : 8 Ahoy! : 7 more : 8 感谢这篇文章有点不具体,(由于沟通),根据我对问题的解释,有一些可能的解决方案 我的第一个脚本filter.awk: $3 <= 3 { next } { print $0 } { te
A : 1
Boy : 3
Ahoy! : 7
more : 8
Ahoy! : 7
more : 8
我必须删除长度小于或等于3个字母的行。输出应如下所示:
A : 1
Boy : 3
Ahoy! : 7
more : 8
Ahoy! : 7
more : 8
感谢这篇文章有点不具体,(由于沟通),根据我对问题的解释,有一些可能的解决方案 我的第一个脚本
filter.awk
:
$3 <= 3 { next }
{ print $0 }
{
text = $1
gsub(/[^[:alpha:]].*$/, "", text)
if (length(text) > 3) { print $0 }
}
测试:
埃德·莫顿指出,这可以做得更短:
$3 > 3
这对我来说也是新的。(可能是这样,我被lex搞糊涂了,它的工作方式正好相反:在lex/flex中,所有不匹配的东西都会被重复。)
更可靠的方法是使用冒号(:
)作为列分隔符(或者类似于在awk:field separator中命名的冒号)。可以通过指定内置变量FS
来更改字段分隔符。这可以通过使用命令行参数-F
或在一个特殊的开始
规则中赋值来完成,该规则始终在开始时执行。(我更喜欢这封信使脚本“独立”
因此,filter2.awk
(即filter.awk
V2.0):
测试:
对OP的另一种解释可能是考虑每行第一列中的连续字母数。为此,一些内置功能开始发挥作用:
gensub()
一个功能强大的替换函数,不幸的是,它只在GNU awk中可用length()
返回字符串的长度(或数组中的元素数)filter2.txt
:
A : 1
Boy : 3
Ahoy! : 7
more : 8
A : 1
Boy : 3
Ahoy! : 7
more : 8
Hello World : 0
Hello! World. : 0
Hi World : 0
filter3.awk
(即filter.awk
V3.0):
测试:
由于在这种情况下字段分隔符不变,因此第一个字段由字符组成,直到第一个空格。模式(^[A-Za-z]+)
捕获文本开头的所有字母,并将它们存储到第一个内部缓冲区中。*$
匹配其余部分,直到文本结束。整个文本将替换为缓冲区\1
。(考虑一下“\\1”
中转义的反斜杠)这在cygwin中的bash上运行良好,因为我曾经在bash初始化中定义过LANG=C
(在遇到德语区域设置问题之后)。Ed Morton(再次)指出,使用[[:alpha:]
而不是[A-Za-z]
应该更健壮
如果您有非GNU awk,则gensub()
不可用。(几周前,另一位大师(他的名声是k)告诉我,世界上没有什么比在世界上呆头呆脑的了。检查到这一点,我意识到即使是我们公司的WWS VS构建链中的AWK实际上是一种呆滞。然而,自从我学会了这一点之后,我多次绊倒了,因为我没有认为解决方案是显而易见的,所以我的答案并不是很好。非GNU awk需要(或隐含地…)
这是我为非GNU awkfilter4.awk提供的第四个版本:
$3 <= 3 { next }
{ print $0 }
{
text = $1
gsub(/[^[:alpha:]].*$/, "", text)
if (length(text) > 3) { print $0 }
}
测试:
对于gsub()
,我恢复了reg ex替换的逻辑:从第一个非字母字符到文本结尾的所有内容都被空字符串替换。(好吧,在gsub()
中甚至不存在类似枚举缓冲区的东西)
临时变量text
的赋值是必要的,因为gsub()
修改其第三个参数的内容。如果我直接提供了$1
(正如我在修复它之前所做的那样),它的内容将会改变,这反过来也会改变$0
的内容,比如awk'length($1)>3'
?您可以使用类似于awk-F:'$2>3'的内容,这里我假设冒号后面的数字就是值,你想继续过滤。你想过滤少于4个,因为示例输出中缺少Boy行。当您说长度小于3个字母时
是指长度小于3个字符
还是包含少于3个字母字符
或包含少于3个连续字母字符
还是其他?你是指整行还是仅在第一个字段中(在:
之前)或其他内容?投入更多的精力提供样本输入/输出,以真正证明您正试图解决的问题-目前,您的输入和输出之间存在太多可能的相关性,无法提供太多帮助。“男孩”有3个字母长,不少于3个,那你为什么要删除它呢?$33
,但无论如何,我不认为这是OP想要的。wrtgensub(/(^[A-Za-z]+).$/,“\\1”,“g”,“$1)
-1)你应该提到的是特定于呆呆的和更新的mawk,2)字符列表依赖于语言环境,使用[:alpha:]
,3)您不能多次匹配^
,因此第三个参数应该是1
,而不是“g”
。我仍然不知道代码实现的是否是OP想要的,当然,因为她还没有告诉我们:-)。
$ awk -f filter3.awk filter2.txt
Ahoy! : 7
more : 8
Hello World : 0
Hello! World. : 0
$
{
text = $1
gsub(/[^[:alpha:]].*$/, "", text)
if (length(text) > 3) { print $0 }
}
$ awk -f filter4.awk filter2.txt
Ahoy! : 7
more : 8
Hello World : 0
Hello! World. : 0
$