linux提取字符串中可能是第二常见模式的部分

myzjeezk  于 2023-01-20  发布在  Linux
关注(0)|答案(6)|浏览(121)

我有几根弦(或目录中的文件名),我需要按第二常见的模式对它们进行分组,然后我将按每个组对它们进行迭代并处理它们。在下面的示例中,我需要2个来自ACCEPT,2个来自BASIC_REGIS,基本上从字符串开始到连字符后的一个字符(-)和可以是任何字符,而不仅仅是数字。第一个最常见的模式是ACCEPT和BASIC_REGIS。我正在使用grep-Po(Perl和唯一匹配)寻找第二个最常见的模式。AWK解决方案正在工作

输入

ACCEPT-zABC-0123
ACCEPT-zBAC-0231
ACCEPT-1ABC-0120
ACCEPT-1CBA-0321

BASIC_REGIS-2ABC-9043
BASIC_REGIS-2CBA-8132
BASIC_REGIS-PCCA-6532
BASIC_REGIS-PBBC-3023

输出

x一个一个一个一个x一个一个二个x
结果:接受-0ABC-
但我需要:验收-0
但是awk解决方案正在工作

echo "ACCEPT-1ABC-0120"|awk '$0 ~ /^A/{print substr($0,1,index($0,"-")+1)}'

验收-1

but5z9lq

but5z9lq1#

***第一个解决方案:***使用所示示例,请尝试以下awk代码。

awk '
match($0,/^(ACCEPT-[0-9]+|BASIC_REGIS-[0-9]+/) && !arr[substr($0,RSTART,RLENGTH)]++
' Input_file

***第二个解决方案:***使用GNU grep,请尝试以下操作。

grep -oP '^.*?-[0-9]+' Input_file | sort -u
wgx48brx

wgx48brx2#

就像这样:

$ grep -Eo '^[^-]+-.' file | sort -u

输出

ACCEPT-0
ACCEPT-1
BASIC_REGIS-2
BASIC_REGIS-9

正则表达式匹配如下:

| 节点|解释|
| - ------|- ------|
| ^|字符串的开头|
| [^-]+|除以下字符之外的任何字符:-(1次或多次(匹配最大可能数量))|
| -|- -|
| .|除\n之外的任何字符|

1cklez4t

1cklez4t3#

我不太清楚你所说的"第二常见的分组"是什么意思,但是简单地重复一下这个输出:

{gn}awk '!NF || !__[$-_  = sprintf("%.*s", index($-_,$(!_+!_)),$-_)]++' FS='-'
   mawk '!NF || !__[$!NF = sprintf("%.*s", index($_, $(!_+!_)),$_) ]++' FS='-'
ACCEPT-0
ACCEPT-1

BASIC_REGIS-2
BASIC_REGIS-9
ne5o7dgx

ne5o7dgx4#

您不需要-P(PCRE),只需要一个简单的BRE:

$ grep -o '^[^-]*-.' file | sort -u
ACCEPT-0
ACCEPT-1
BASIC_REGIS-2
BASIC_REGIS-9

或者单独使用GNU awk:

$ awk 'match($0,/^[^-]*-./,a) && !seen[a[0]]++{print a[0]}' file
ACCEPT-0
ACCEPT-1
BASIC_REGIS-2
BASIC_REGIS-9

或任何awk:

$ awk '!match($0,/^[^-]*-./){next} {$0=substr($0,1,RLENGTH)} !seen[$0]++' file
ACCEPT-0
ACCEPT-1
BASIC_REGIS-2
BASIC_REGIS-9
r1zhe5dt

r1zhe5dt5#

POSIX shell 有原始参数扩展。使用此函数的含义:

${string#-*} # Remove first ‘-‘ and everything after

与此相结合:

${string#*-} # Remove first ‘-‘ and everything before
    • 可以提取第n个最常见的模式。**

例如:

input="ACCEPT-0ABC-0123"

common_pattern_base=${input#-*} # Result → ACCEPT
next_level=${input#*-} # Result → 0ABC-0123

common_pattern_mid=${next_level#-*} # Result → 0ABC
next_level_again=${next_level#*-} # Result → 0123

现在我做得很粗糙,但它应该作为一个例子,说明这个工具是多么简单和强大,特别是在与循环结合使用时。
如果您需要某种语法,现在可以简单地处理各个部分:

# Result of line below → 0
trim_pattern_mid=“$(echo ${common_pattern_mid} | cut -c1)”

# Result of line below → ACCEPT-0
format=“${common_pattern_base}-${trim_pattern_mid}”

虽然这个答案比较长,但它比使用正则表达式更灵活和简单。想象一下,想要用正则表达式得到一个256长链的第四个模式,这是一场噩梦。
这个答案更适合于脚本,如果是临时的,grep或sed就可以了--至少对于小模式是这样。

ygya80vv

ygya80vv6#

由于不调用substr,因此效率更高:

awk -v{,O}FS='-' '{printf("%s-%c\n",$1,$2)}' file

相关问题