![Unix awk 用倒问号替换内部单引号](https://linux22.com/image/136109/Unix%20awk%20%E7%94%A8%E5%80%92%E9%97%AE%E5%8F%B7%E6%9B%BF%E6%8D%A2%E5%86%85%E9%83%A8%E5%8D%95%E5%BC%95%E5%8F%B7.png)
我想用倒问号 (¿) 替换内部单引号(忽略外部单引号)。我正在使用下面的awk
命令,但它不起作用。分号是分隔符。
awk -F "'" -v OFS="'" '{for (i=2; i<=NF; i+=2) gsub("'","\302\277", $i } 1' filename
数据是:
'gasg'dhsh';'dhdjs'
答案1
¿
要替换文件中单词两侧的所有单引号(假设bash
使用了 ,以便我们可以使用$'...'
):
q=$'\302\277'
sed "s/\>'\</$q/g" file
或者
q=$( printf '\302\277' )
sed "s/\>'\</$q/g" file
或者
sed "s/\>'\</¿/g" file
根据给定的输入,这将产生
'gasg¿dhsh';'dhdjs'
该模式\>'\<
将匹配任何'
紧邻其前后具有单词字符的模式。字符;
和行首/行尾不是单词字符,而 和g
都是d
。
您的代码存在三个主要问题:
shell 中的单引号字符串可能永远不会包含单引号。调用中嵌入的单引号
gsub()
将结束作为代码的单引号字符串awk
,从而产生语法错误。使用将输入字段分隔符设置为单引号
-F "'"
将导致awk
将输入拆分为所有单引号。这意味着该awk
程序将绝不看到任何单引号,gsub()
因此您将永远不会替换任何内容。该字符串
\302\277
不是倒置的问号,除非解释为转义序列。
纠正所有这些问题将使程序正常运行,但它将替换所有出现的单引号:
$ awk -F ';' -v OFS=';' '{ for (i=1; i<=NF; ++i) gsub("'"'"'", sprintf("\302\277"), $i); print }' file
¿gasg¿dhsh¿;¿dhdjs¿
答案2
假设“内部单引号”意味着存在“外部单引号”,并且还假设这些外部引号位于每个字段的开头和结尾(在本例中由“;”分隔),您可以使用:
$ awk -F ';' '{OFS=FS;for(j=1;j<=NF;j++){gsub(q,i,$j);sub("^"i,q,$j);sub(i"$",q,$j)}}{print}' q='\047' i='¿'
'gasg¿dhsh';'dhdjs'