新手用bash的sed这样替换怎么不成功呢?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了新手用bash的sed这样替换怎么不成功呢?相关的知识,希望对你有一定的参考价值。

大佬好,因为刚接触这个,尝试用sed命令替换本目录的.xmp文本里的两行文本,不知道为啥不成功呢,请大佬指点一二,不胜感激~~
#!/bin/bash
read -r -d '' old << EOM
<rdf:Alt>
<rdf:li xml:lang="x-default">秋季</rdf:li>
EOM
echo "$old"
read -r -d '' new << EOM
$ echo "$new"=
<rdf:Alt>
<rdf:li xml:lang="x-default">New_冬季</rdf:li>
EOM
echo "$new"
sed -i 's/"$old"/"$new"/g' *.xmp

您的 sed 命令替换文本的方法不正确。首先,由于您在脚本中定义了 old 和 new 变量,所以在 sed 命令中不能直接使用 "$old" 和 "$new",需要使用 $old 和 $new 代替。
其次,您在定义 old 变量时,在 EOM 标记之间有多余的换行符,会导致 sed 命令执行失败。此外,您在定义 new 变量时,在结尾处的换行符也会导致 sed 命令失败。因此,您可以修改脚本如下:
#!/bin/bash
read -r -d '' old << EOM
<rdf:Alt>
<rdf:li xml:lang="x-default">秋季</rdf:li>
EOM
echo "$old"
read -r -d '' new << EOM
<rdf:Alt>
<rdf:li xml:lang="x-default">New_冬季</rdl:li>
EOM
echo "$new"
sed -i "s/$old/$new/g" *.xmp
最后,如果您要替换的文本中包含特殊字符(例如 / 字符),那么还需要对这些特殊字符进行转义,以避免 sed 命令执行错误。例如,如果您要替换的文本中包含 / 字符,那么您可以将该字符替换为 /,然后再使用 sed 命令进行替换。追问

不行呢,你做个文件替换试试,不知道问题在哪

参考技术A 这样写会有一些问题。首先,sed命令中使用双引号包含的字符串会把其中的特殊字符(如换行符)当作普通字符处理,而不会按照其原本的含义进行处理。因此,在您的代码中,替换的字符串中的换行符不会起作用。
其次,您将两个变量($old 和 $new)用在了 sed 命令的替换模式(s///)中,但是没有在前面加上$符号来引用它们。由于没有这个符号,shell 会把这些变量名当作普通字符串处理,并不会替换为它们所代表的值。
为了解决这些问题,可以按照下面的方式修改代码:
#!/bin/bash
read -r -d '' old << EOM
rdf:Alt
<rdf:li xml:lang="x-default">秋季</rdf:li>
EOM
read -r -d '' new << EOM
rdf:Alt
<rdf:li xml:lang="x-default">New_冬季</rdf:li>
EOM
sed -i "s/$old/$new/g" *.xmp
这样,您的代码就能够正常工作了。

在 bash 中使用 sed 替换 csv 行的第 n 个值

【中文标题】在 bash 中使用 sed 替换 csv 行的第 n 个值【英文标题】:replace nth value of a csv line using sed in bash 【发布时间】:2021-10-16 22:28:23 【问题描述】:

我有一些像下面这样的 csv

uid_01, joe, yes, no 
uid_02, sam, yes, maybe
uid_03, c, ruth, yes, maybe
uid_04, **alan**, no, yes

我想用 ruby 替换 alan,uid 在这里是唯一的。我需要根据 $position 进行更改,知道如何在 sed 中获得它吗?

我还想同时给出模式和替换值作为参数。

尝试过类似的方法,但仅在最后一次输入时有效

sed -i '/^'$uid',/s/[^,]*$/'$returnvalue'/' $OUTPUT

先谢谢了,请帮忙!

【问题讨论】:

【参考方案1】:

awk 更适合:

awk -v id='uid_04' -v repl='ruby' 'BEGIN FS=OFS=", "
$1 == id $2 = repl 1' file.csv

uid_01, joe, yes, no
uid_02, sam, yes, maybe
uid_03, c, ruth, yes, maybe
uid_04, ruby, no, yes

【讨论】:

谢谢。有没有办法在不复制的情况下覆盖同一个文件? 如果您有gnu-awk,请使用awk -i inplace -v id='uid_04' -v repl='ruby' 'BEGIN FS=OFS=", " $1 == id $2 = repl 1' file.csv @SankaranKutty 每个具有启用“就地”编辑选项的 Unix 工具(gawk -i inplaceperl -iruby -ised -i 等)都会获取文件的副本,因此- 您真的是否关心获取文件的副本,或者您只是不想在代码中使用cmd file &gt; tmp &amp;&amp; mv tmp file 明确地执行此操作,而是更喜欢cmd -i filecmd -i inplace file awk -v id1=$id -v repl='PASS' 'BEGIN FS=OFS="," ($1 == id1)$6 = repl 1' $OUTPUT > tmp && mv tmp $OUTPUT 使它工作,谢谢大家。 :) @EdMorton - 新手,gawk 没有出现在盒子里,所以我会暂时使用这个。感谢您的回复。 @anubhava 谢谢你能告诉我 1 附近的文件名是做什么的吗?【参考方案2】:

这可能对你有用(GNU sed):

id='uid_04' name='ruby' position=2
sed -i "/^$id,/s/[^,]*/ $name/$position" file

如果 id 是uid_04,则将第二个字段替换为ruby

【讨论】:

对不起,它不起作用,sed:替换表达式中的错误选项

以上是关于新手用bash的sed这样替换怎么不成功呢?的主要内容,如果未能解决你的问题,请参考以下文章

用 Bash 变量替换 sed

sed 用 Bash 变量替换

用文件的内容替换某些标记(使用 bash 脚本)

用 Bash 脚本中的 sed 替换文件中的版本号

在 bash 中使用 sed 替换 csv 行的第 n 个值

如何在没有sed的情况下替换csv文件中的一行[重复]