选择单词中的所有文本,第一个字母除外

时间:2014-05-21 19:47:16

标签: regex awk

您喜欢更改单词中的所有文字,但第一个字母除外。

cat file
TEST
BEST

然后我想我能做到:

awk '{sub(/[^.].*/,"X",$1)}1' file
X
X

这是我的预期输出:

TX
BX

这没关系

awk '{sub(/[^B].*/,"X",$1)}1' file
X
BX

这也没关系

awk '{sub(/[^BT].*/,"X",$1)}1' file
TX
BX

但这不行

awk '{sub(/[^A-Z].*/,"X",$1)}1' file
TEST
BEST

awk '{sub(/[^a-z].*/,"X",$1)}1' file
X
X

我知道这有一些我的角色。


然后我测试了这个,没有工作

awk '{sub(/[^[:alpha:]].*/,"X",$1)}1' file
TEST
BEST

还有锚。

awk '{sub(/^[^.].*$/,"X",$1)}1'
X
X

有关如何正确理解的想法吗?

4 个答案:

答案 0 :(得分:3)

您可能希望使用捕获的组捕获第一个字母,然后替换所有内容。这可以使用gensub(在GNU awk版本3.2或更高版本中提供)。

$ cat file
TEST
BEST
$ awk '{print gensub(/(.).*/,"\\1X","g",$0)}' file
TX
BX

为什么以下解决方案不起作用:

awk '{sub(/[^[:alpha:]].*/,"X",$1)}1' file

嗯,这很简单。您的RE告诉awk选择任何不包含以[:alpha:]字符类开头的字符串的内容,因为您的数据没有,没有选择任何内容,您的文件打印为是。

如果您将文件修改为:

$ cat file
TEST
BEST
%HELLO

$ awk '{sub(/[^[:alpha:]].*/,"X",$1)}1' file
TEST
BEST
X

awk解决方案:

使用awk执行此操作的一种方法是在首字母中添加一个唯一字符,然后使用gsub删除其余字符(请考虑使用方法)。

$ awk '{sub(/./,"&\n",$1);gsub(/\n.*/,"X",$1)}1' file
TX
BX

您可以使用SUBSEP作为唯一字符来区分两个部分。 SUBSEP是一个awk内置变量,它包含一个非打印字符,可以让您轻松地从数据本身中选择一些内容。

$ awk '{sub(/./,"&SUBSEP",$1);gsub(/SUBSEP.*/,"X",$1)}1' file
TX
BX

答案 1 :(得分:1)

$ awk '/../{print substr($1,1,1)"X"}' file
TX
BX

其他方法

awk '{sub(/[^A-Z].*/,"X",$1)}1' file
TEST
BEST

上述方法不起作用,因为正则表达式永远不会匹配:字符串只有大写字母。

awk '{sub(/[^a-z].*/,"X",$1)}1' file
X
X

上面替换了整个字符串,因为它匹配整个字符串。

awk '{sub(/[^[:alpha:]].*/,"X",$1)}1' file
TEST
BEST

因为文件中的所有字符都是alpha,所以上述正则表达式永远不会匹配。

据我所知,awk的sub缺乏先进的正则表达式设施,例如分组或回顾,可以让它在这里工作。

答案 2 :(得分:0)

在非GNU awk中执行此操作的方法是:

$ awk '{print substr($0,1,1) "X"}' file
TX
BX

如果您需要,可以使用RE:

awk 'match($0,/.[[:alpha:]]+/){ $0 = substr($0,1,RSTART) "X" substr($0,RSTART+RLENGTH) } 1' file

一般来说,你需要gnsk中的gensub(),你可以使用match()+ substr()(有时在循环中)在非GNU awks中完成。

如果您有一些不适用的输入,请更新您的问题以包含该输入以及预期的输出。

答案 3 :(得分:0)

你可以用......如下:

awk '{sub(/EST/,"X")}1' file
TX
BX