如何用sed代替一部分线?

时间:2022-02-05 16:47:40

I have a file which contains many lines(line delimiter is ~). Each line,I have many elements which is seperated by a delimiter '*'. What I want to do is , I will be having a line that starts with string TRN in my file. It can have 4(including TRN) or more data points in it. Something like,

我有一个包含许多行的文件(行分隔符是〜)。每一行,我有许多元素,用分隔符'*'分隔。我想要做的是,我将在我的文件中有一个以字符串TRN开头的行。它可以包含4个(包括TRN)或更多数据点。就像是,

TRN*1*S521000035*1020494919~
TRN*1*S521000035*1020494919*787989800~

I want to replace the fourth data point from this lines to abc123. ie,

我想将这行中的第四个数据点替换为abc123。即

TRN*1*S521000035*abc123~
TRN*1*S521000035*abc123*787989800~

I tried using sed command with regular expression

我尝试使用正则表达式的sed命令

sed -i 's/^TRN\*(.*)\*(.*)\*(.*)$/abc123/g' file.txt 

But the whole string is getting replaced to abc123.

但是整个字符串都被替换为abc123。

Is it possible to change only its 4th datapoint using sed command ?

是否可以使用sed命令仅更改其第4个数据点?

5 个解决方案

#1


2  

Using GNU sed:

使用GNU sed:

$ sed -r -i 's/^((\w+\*){3})\w*(.*)/\1abc123\3/g' file.txt

Output:

TRN*1*S521000035*abc123~
TRN*1*S521000035*abc123*787989800~ 

#2


2  

sed is your friend.

sed是你的朋友。

Give a try to this tested version:

尝试这个测试版本:

$ sed "s/^\(TRN[*][^*][^*]*[*][^*][^*]*[*]\)[^*][^*]*\(.*~\)/\1abc123\2/" afile.txt
TRN*1*S521000035*abc123~
TRN*1*S521000035*abc123*787989800~

You might want to read the man pages to have more details on regexp and sed

您可能希望阅读手册页以获得有关regexp和sed的更多详细信息

#3


1  

This might work for you (GNU sed):

这可能适合你(GNU sed):

sed 's/[^*~]\+/abc123/4' file

Replace the fourth occurrence of something which is does not contain a ~ or a * with abc123.

用abc123替换第四次出现的不包含〜或a *的内容。

#4


0  

AWK should do the trick in a pretty concise and readable way. FS changes the field separator so that you can identify where you want it to break inside of a line.

AWK应该以非常简洁和可读的方式完成这个技巧。 FS会更改字段分隔符,以便您可以确定要在行内打破的位置。

$ awk 'BEGIN { FS="*|~" }{ sub($4, "abc123"); print $0}' file.txt

TRN*1*S521000035*abc123~
TRN*1*S521000035*abc123*787989800~

#5


0  

While you can do this with sed it is much easier to achieve the desired effect with awk. The program awk is especially useful to analyse and transform tabular-structured data, as in your case:

虽然你可以使用sed来实现这一点,但使用awk实现所需的效果要容易得多。 awk程序对于分析和转换表格结构数据特别有用,如你的情况:

awk -F'*' -v OFS='*' '{$4 = "abc123"; print}'

This reads:

awk         Run the program awk
 -F'*'      Use the * as a field delimiter on input
 -v OFS='*' Use the * as a field delimiter on output
 '{         On each record …
   $4 = "abc123";
            … set the 4th field to "abc123"
   print
            … and print the curent record
  }'

It is also easy to expand on that example to selectively replace the 4-th field, depending on the value of the other fields.

根据其他字段的值,也可以很容易地扩展该示例以选择性地替换第4个字段。

#1


2  

Using GNU sed:

使用GNU sed:

$ sed -r -i 's/^((\w+\*){3})\w*(.*)/\1abc123\3/g' file.txt

Output:

TRN*1*S521000035*abc123~
TRN*1*S521000035*abc123*787989800~ 

#2


2  

sed is your friend.

sed是你的朋友。

Give a try to this tested version:

尝试这个测试版本:

$ sed "s/^\(TRN[*][^*][^*]*[*][^*][^*]*[*]\)[^*][^*]*\(.*~\)/\1abc123\2/" afile.txt
TRN*1*S521000035*abc123~
TRN*1*S521000035*abc123*787989800~

You might want to read the man pages to have more details on regexp and sed

您可能希望阅读手册页以获得有关regexp和sed的更多详细信息

#3


1  

This might work for you (GNU sed):

这可能适合你(GNU sed):

sed 's/[^*~]\+/abc123/4' file

Replace the fourth occurrence of something which is does not contain a ~ or a * with abc123.

用abc123替换第四次出现的不包含〜或a *的内容。

#4


0  

AWK should do the trick in a pretty concise and readable way. FS changes the field separator so that you can identify where you want it to break inside of a line.

AWK应该以非常简洁和可读的方式完成这个技巧。 FS会更改字段分隔符,以便您可以确定要在行内打破的位置。

$ awk 'BEGIN { FS="*|~" }{ sub($4, "abc123"); print $0}' file.txt

TRN*1*S521000035*abc123~
TRN*1*S521000035*abc123*787989800~

#5


0  

While you can do this with sed it is much easier to achieve the desired effect with awk. The program awk is especially useful to analyse and transform tabular-structured data, as in your case:

虽然你可以使用sed来实现这一点,但使用awk实现所需的效果要容易得多。 awk程序对于分析和转换表格结构数据特别有用,如你的情况:

awk -F'*' -v OFS='*' '{$4 = "abc123"; print}'

This reads:

awk         Run the program awk
 -F'*'      Use the * as a field delimiter on input
 -v OFS='*' Use the * as a field delimiter on output
 '{         On each record …
   $4 = "abc123";
            … set the 4th field to "abc123"
   print
            … and print the curent record
  }'

It is also easy to expand on that example to selectively replace the 4-th field, depending on the value of the other fields.

根据其他字段的值,也可以很容易地扩展该示例以选择性地替换第4个字段。