新手用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
其次,您在定义 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 inplace
、perl -i
、ruby -i
、sed -i
等)都会获取文件的副本,因此- 您真的是否关心获取文件的副本,或者您只是不想在代码中使用cmd file > tmp && mv tmp file
明确地执行此操作,而是更喜欢cmd -i file
或cmd -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这样替换怎么不成功呢?的主要内容,如果未能解决你的问题,请参考以下文章