在字符串中的x,y,z位置插入一个字符

问题描述 投票:1回答:3

我需要在2个字符之后在下面的字符串中插入“ - ”减号,然后在3个字符之后插入:

mystring="223334444"

和期望的输出如:22-333-4444

我可以通过以下问题插入固定长度的字符,

https://unix.stackexchange.com/questions/5980/how-do-i-insert-a-space-every-four-characters-in-a-long-line

但在我的情况下,分裂不是静态的(不是在每个第n个位置之后,而是在x,y,z位置之后),我需要一个表达式来使用sed完成这项工作。

更新我可以使用多个sed命令来实现所需的格式,例如:echo 111111111 | sed 's/.\{2\}/&-/' | sed 's/.\{6\}/&-/'

但我需要知道如何使用单个表达式实现它

添加更多信息//抱歉我之前错过了

输出22-333-444将用于某些搜索(使用grep),我可能需要进行数千次这些转换,然后对输出字符串进行搜索,因此这里处理速度/优化也是可取的。

添加有关在评论中按要求搜索零件的信息

inputfile示例:

135311046
135310897
135311354
135310944
125312732
125222083
415211804
415222255
415204163
415206020

我在一个while循环中逐行读取这个文件,在变量line

我想要做的是将此字符串135311046转换为13-531-1046然后对文件执行grep。

我目前正在使用以下替换grep $(echo $line | sed 's/.\{2\}/&-/' | sed 's/.\{6\}/&-/') datafile.txt

datafile包含如下数据:

Line1.P2.ON28.C1.P1.FL1,12-522-2083
Line1.P1.ON19.C1.P1.FL1,12-522-2112
Line1.P1.ON34.C1.P1.FL1,12-530-2766
Line1.P2.ON15.C1.P1.FL1,12-531-1041
Line1.P2.ON15.C1.P3.FL1,12-531-1041
Line1.P2.ON15.C1.P4.FL1,12-531-1041
Line1.P1.ON39.C1.P1.FL1,12-531-1094
Line1.P2.ON26.C1.P1.FL1,12-531-2732
Line1.P1.ON57.C1.P1.FL1,12-533-4019

所以我的主要要求是以一种漂亮/紧凑的方式进行转换,因为这些是我需要在另一个文件中搜索的数千行,所以需要快速/优化

regex awk sed command-line text-processing
3个回答
2
投票

使用awk:

$ echo $mystring | awk 'BEGIN{FS=OFS=""}{$2=$2 "-";$5=$5 "-"}1'
22-333-4444

解释:

awk 'BEGIN {
    FS=OFS=""   # field separators to null, ie. each char on an individual field
}{
    $2=$2 "-"   # set dashes to all the right places
    $5=$5 "-"
}1'             # output

在GNU awk,mawk,Busybox awk和BWK awk版本20121220上成功测试。

更新:我想要做的是将此字符串135311046转换为13-531-1046然后对文件执行grep。一体化awk程序:

$ awk '
BEGIN {
    OFS=""
}
NR==FNR {
    $2=$2 "-";$5=$5 "-"
    a[$0]
    next
}
$NF in a' FS="" input FS="," data

输出:

Line1.P2.ON28.C1.P1.FL1,12-522-2083
Line1.P2.ON26.C1.P1.FL1,12-531-2732

在GNU awk,mawk和Busybox awk上成功测试。 BWK awk版本20121220失败。


3
投票

编辑:由于OP编辑了完整要求的帖子,所以现在添加解决方案。

awk '
FNR==NR{
  a[substr($0,1,2)"-"substr($0,3,3)"-"substr($0,6)]
  next
}
($NF in a)'   Input_file1  FS=","  Input_file2

它应该适用于任何awk恕我直言。输出如下。

Line1.P2.ON28.C1.P1.FL1,12-522-2083
Line1.P2.ON26.C1.P1.FL1,12-531-2732


第一个解决方案:你可以尝试下面的。在这里,我将-放在前2个字符之后,然后是3个字符之后。在这里,我使用sed的功能,通过使用\(..\)将值存储到内存中,这意味着让sed知道将前2个字符保存到内存中(以后可以通过使用\ 1来访问)同样我们可以创建更多内存占位符并可以访问它们替换部分后他们的数字。

mystring="223334444"
echo "$mystring" | sed 's/\(..\)\(...\)\(....\)/\1-\2-\3/'

第二个解决方案:或者如果你想用字符串的值替换所有2和3的全部(这不取决于2s和3s的位置,它将简单地用字符串中的任何地方替换它们)然后尝试跟随。

echo "$mystring" | sed -E 's/2+|3+/&-/g'

输出如下。

22-333-4444

2
投票

作为替代方案,您可以在没有任何正则表达式的bash中执行此操作:

mystring="223334444"
echo "${mystring:0:2}-${mystring:2:3}-${mystring:5}"

22-333-4444
© www.soinside.com 2019 - 2024. All rights reserved.