Bash 如何使用unix shell脚本/命令将文件中的单引号(')替换为双引号(“)?不能替换撇号

Bash 如何使用unix shell脚本/命令将文件中的单引号(')替换为双引号(“)?不能替换撇号,bash,shell,sed,ksh,Bash,Shell,Sed,Ksh,我试图在Unix中用双引号替换文件中的单引号,而不是撇号。撇号必须保持原样 我通过顺序执行3个sed命令获得了所需的输出。但是,我无法处理最后一行“假新闻” sed -i 's/'\''/"/g' test.txt sed -i 's/"s/'\''s/g' test.txt sed -i 's/s"/s'\''/g' test.txt 第一个sed-将所有单引号转换为双引号 第二个sed-转换所有双引号,后跟带单引号的s 第三个sed-转换所有s,后跟双引号和单引号 输入文件- Hell

我试图在Unix中用双引号替换文件中的单引号,而不是撇号。撇号必须保持原样

我通过顺序执行3个sed命令获得了所需的输出。但是,我无法处理最后一行“假新闻”

sed -i 's/'\''/"/g' test.txt

sed -i 's/"s/'\''s/g' test.txt

sed -i 's/s"/s'\''/g' test.txt
第一个sed-将所有单引号转换为双引号

第二个sed-转换所有双引号,后跟带单引号的s

第三个sed-转换所有s,后跟双引号和单引号

输入文件-

Hello Sir!
How are you?
How's your health?
All 'good'?
Charles' here.
'fake news'
预期产量-

Hello Sir!
How are you?
How's your health?
All "good"?
Charles' here.
"fake news"
要复制三个sed,可以使用单个perl正则表达式:

编辑:“假新闻”案:

您可以通过以下方式处理一半的“假新闻”案件:

perl -p -e 's/([^s]|^)'\''([^s])/$1"$2/g' test.txt
要管理新闻的大小写,需要定义单引号可接受的单词列表名称和姓氏。否则,您可以添加以下过程,在不以大写字母开头的单词后更改引号:

perl -p -e 's/([^\w][a-z]+)s'\''/$1s"/g' test.txt
在带有管道的单个命令中:

perl -p -e 's/([^s]|^)'\''([^s])/$1"$2/g' test.txt | perl -p -e 's/([^\w][a-z]+)s'\''/$1s"/g' 
这就产生了:

你好,先生

你好吗

你身体怎么样

都好吗

查尔斯在这儿

假新闻

假消息


您可以在一次sed调用中运行所有命令:

sed 's/'\''/"/g;s/"s/'\''s/g;s/s"/s'\''/g'


这可以通过一个替换命令实现您的要求:

$ sed -E "s/'([^']*)'/\"\1\"/g" file
Hello Sir!
How are you?
How's your health?
All "good"?
Charles' here.
"fake news"
上面的工作原理是用成对的双引号替换成对的单引号

“[^']*”与后跟任何字符的单引号匹配,而不是后跟单引号的单引号。单引号内的字符保存在捕获组1中。替换项\\1\将捕获组置于双引号内

虽然这可以处理您要求的案例,但很容易想象,如果没有复杂的语言分析,就无法处理更复杂的案例

另类风格 可以使用替代但等效的shell引用样式编写与上述相同的命令:

sed -E 's/'\''([^'\'']*)'\''/"\1"/g' file

你如何处理“假新闻”?@ Copba是的,我写的3个SED命令将不能处理“假新闻”。我需要解决这个问题。对于任何解决方案,考虑它如何处理一条线,比如“好的,你在思考”。SED真的无法区分一般的引号和撇号。甚至连狗的玩具都坏了。d-完全无法区分带有regexp的引号和“此处停止”之类的内容。使用“作为撇号,而不是”作为正确的排版。或“s/?”这很有效。但根据@choroba对我问题的评论,如果“假新闻”写在输入文件中,则此命令将无法实现目标。正如您在评论中提到的,3 sed命令将无法处理“假新闻”。但是,将所有3 sed命令合并并作为一个命令调用确实很有帮助。但是需要找到一种处理“假新闻”的方法。好的,这是赢家。我尝试使用\B而不是单词边界,但最终使用了Charles。在我找到解决方案之前,您就已经获得了它。从s开始ed-r s/\B'|'\B/\/g文件,并试图从那里开始工作…我的评论“Its good your't thinkin”中的输入失败。它将其转换为“Its good your't thinkin”,而不是将所有三个撇号都保留不变。是的,@chepner,虽然我们可以围绕该示例工作,正如我的回答所述和你的评论所暗示的,但还有其他情况下如果没有完整的语言分析,我们根本无法解决这个问题,这超出了本文的范围。
$ sed -E "s/'([^']*)'/\"\1\"/g" file
Hello Sir!
How are you?
How's your health?
All "good"?
Charles' here.
"fake news"
sed -E 's/'\''([^'\'']*)'\''/"\1"/g' file