sed 命令在找到特定模式后替换特定值

发布于 2024-12-08 21:44:38 字数 620 浏览 0 评论 0原文

我对 unix 命令有点困惑。

我有一个名为 file.txt 的文件,其中包含以下内容:

Customer1

name=Alice

pass=unix

dob=

Customer2

name=Destroyer

pass=windows

dob=

我基本上想要的是使用一个允许我为客户 grep 的 unix 命令(即 Customer1)然后给它的 dob 一个值,例如 dob=1912

这样 file.txt 将变得像

Customer1

name=Alice

pass=unix

dob=1912

我一直在工作使用 sed,这是我制定的命令:

sed "s/$(awk 'c-->0;/Customer1/{c=3}' file.txt | tail -1)/dob=1234/g" - i file.txt

然而,这会将所有出现的 dob 替换为 dob=1234 (非常明显)。

有人可以给我一些关于如何锁定每个客户的特定 dob 并替换它的提示吗?

提前致谢。

I'm a bit stuck with a unix command.

I have a file called file.txt with the following content:

Customer1

name=Alice

pass=unix

dob=

Customer2

name=Destroyer

pass=windows

dob=

What I basically want is to use a unix command that would allow me to grep for the customer (i.e Customer1) then give its dob a value, say for example dob=1912

so the file.txt will become like

Customer1

name=Alice

pass=unix

dob=1912

I've been working with sed, here's the command that I formulated:

sed "s/$(awk 'c-->0;/Customer1/{c=3}' file.txt | tail -1)/dob=1234/g" -i file.txt

This however will replace ALL occurrences of dob with dob=1234 (quite obvious).

Can someone give me a hint on how to lock on the specific dob for each customer and replace it?

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

弱骨蛰伏 2024-12-15 21:44:38

awk 可以自己完成。请参阅下面的一行:

 awk 'BEGIN{RS="dob=";OFS="\n\n"}$1~/Customer1/{$0=$0"dob=1234";print}' input

test :将 customer1 的 dob 值更改为 7777:

kent$  cat t.txt
Customer1

name=Alice

pass=unix

dob=

Customer2

name=Destroyer

pass=windows

dob=

kent$  awk 'BEGIN{RS="dob=";OFS="\n\n"}$1~/Customer1/{$0=$0"dob=7777";print}' t.txt

Customer1

name=Alice

pass=unix

dob=7777

更新:

kent$  awk 'BEGIN{RS="dob=";OFS="\n\n"}$1~/Customer1/{$0=$0"dob=7777";print > "t.txt"}' t.txt

kent$  cat t.txt
Customer1

name=Alice

pass=unix

dob=7777

再次更新

kent$  awk '/Customer1/{a++;}/dob=/&&a{$0="dob=7777";a=0;}1' t.txt > tmp.txt && mv tmp.txt t.txt

kent$  cat t.txt
Customer1

name=Alice

pass=unix

dob=7777

Customer2

name=Destroyer

pass=windows

dob=

使用 sed 更新
实际上,使用 sed (带有方便的 -i 选项)来处理这个问题也是可能的。我没有正确理解您的要求,我以为您只想要特定的客户块。所以我选择了awk。现在是 sed 版本:

kent$  sed -ir '/Customer1/{x;s/.*/a/;x;} 
/dob=/{x;
        /a/{s/a//g; x;
                s/.*/dob=1234/; x;};
        x}' t.txt

kent$  cat t.txt
Customer1

name=Alice

pass=unix

dob=1234

Customer2

name=Destroyer

pass=windows

dob=

awk can do it by itself. see the one liner below:

 awk 'BEGIN{RS="dob=";OFS="\n\n"}$1~/Customer1/{$0=$0"dob=1234";print}' input

test : change customer1's dob value to 7777:

kent$  cat t.txt
Customer1

name=Alice

pass=unix

dob=

Customer2

name=Destroyer

pass=windows

dob=

kent$  awk 'BEGIN{RS="dob=";OFS="\n\n"}$1~/Customer1/{$0=$0"dob=7777";print}' t.txt

Customer1

name=Alice

pass=unix

dob=7777

updated:

kent$  awk 'BEGIN{RS="dob=";OFS="\n\n"}$1~/Customer1/{$0=$0"dob=7777";print > "t.txt"}' t.txt

kent$  cat t.txt
Customer1

name=Alice

pass=unix

dob=7777

updated again

kent$  awk '/Customer1/{a++;}/dob=/&&a{$0="dob=7777";a=0;}1' t.txt > tmp.txt && mv tmp.txt t.txt

kent$  cat t.txt
Customer1

name=Alice

pass=unix

dob=7777

Customer2

name=Destroyer

pass=windows

dob=

updated with sed
actually, using sed (with convenient -i option) to handle this is also possible. I didn't understand your requirement correctly, I thought you only want the specific Customer Block. so I picked awk. Now comes the sed version:

kent$  sed -ir '/Customer1/{x;s/.*/a/;x;} 
/dob=/{x;
        /a/{s/a//g; x;
                s/.*/dob=1234/; x;};
        x}' t.txt

kent$  cat t.txt
Customer1

name=Alice

pass=unix

dob=1234

Customer2

name=Destroyer

pass=windows

dob=
近箐 2024-12-15 21:44:38

您可以使用 awk 的模式匹配来限制行的范围。例如,(假设您的输入文件使用“user”而不是“name”,正如您给出的两个示例一样):

$ awk /user=alice/,/^Customer/{ if( $0 == "dob=" ) $0="dob=1234"} {print} file.txt

应将 alice's dob 替换为“1234”

如果您有 gnu sed,则可以使用 -i 来替换文件(在执行此操作之前进行测试)。或者根据需要使用重定向。

You can use awk's pattern matching to limit the range of lines. For example, (assuming your input file uses "user" instead of "name", as you give both examples):

$ awk /user=alice/,/^Customer/{ if( $0 == "dob=" ) $0="dob=1234"} {print} file.txt

Should replace alice's dob with "1234"

If you have gnu sed, you can use -i to replace the text in the file (test it before you do that). Or use redirections as needed.

野心澎湃 2024-12-15 21:44:38

在这种情况下,使用 awk 可能会有所帮助:

 searchfor=Customer1
 replacefield=dob
 newvalue=1912

 awk -F'=' '
   /^'"$searchfor"'$/ { do_something = 1 }
   do_something && $1 == "'"$replacefield"'" { print $1 "='"$newvalue"'"; do_something = 0; next }
   { print }
 ' dat1

In this case using awk could help:

 searchfor=Customer1
 replacefield=dob
 newvalue=1912

 awk -F'=' '
   /^'"$searchfor"'$/ { do_something = 1 }
   do_something && $1 == "'"$replacefield"'" { print $1 "='"$newvalue"'"; do_something = 0; next }
   { print }
 ' dat1
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文