Bash 用“替换引号”``&引用;及''&引用;

Bash 用“替换引号”``&引用;及''&引用;,bash,quotes,tex,Bash,Quotes,Tex,我有一个包含许多“标记的文档,但我想将其转换为TeX格式 TeX使用2'标记作为起始引号,2'标记作为结束引号 我只想在“”以偶数形式出现在一行时(例如,行上有2、4或6个”)对这些进行更改 "This line has 2 quotation marks." --> ``This line has 2 quotation marks.'' "This line," said the spider, "Has 4 quotation marks." --> ``This line,

我有一个包含许多
标记的文档,但我想将其转换为TeX格式

TeX使用2'标记作为起始引号,2'标记作为结束引号

我只想在“
以偶数形式出现在一行时(例如,行上有2、4或6个
)对这些进行更改

"This line has 2 quotation marks."
--> ``This line has 2 quotation marks.''

"This line," said the spider, "Has 4 quotation marks."
--> ``This line,'' said the spider, ``Has 4 quotation marks.''

"This line," said the spider, must have a problem, because there are 3 quotation marks."
--> (unchanged)
我的句子从不跨行,所以不需要检查多行

很少有单引号的引号,所以我可以手动更改它们


如何转换这些内容?

这是我的一行代码,适用于我:

awk -F\" '{if((NF-1)%2==0){res=$0;for(i=1;i<NF;i++){to="``";if(i%2==0){to="'\'\''"}res=gensub("\"", to, 1, res)};print res}else{print}}' input.txt >output.txt
使用
awk
解释

awk '{
  n=gsub("\"","&") # set n to the number of quotes in the current line
}
!(n%2){ # if there are even number of quotes
  while(n--){ # as long as we have double-quotes
    n%2?Q=q:Q="`" # alternate Q between a backtick and single quote
    sub("\"",Q Q) # replace the next double quote with two of whatever Q is
  }
}1 # print out all other lines untouched' 
q=\' in # set the q variable to a single quote and pass the file 'in' as input
使用
sed

下面是我使用重复的
sed
的一行代码:

cat file.txt | sed -e 's/"\([^"]*\)"/`\1`/g' | sed '/"/s/`/\"/g' | sed -e 's/`\([^`]*\)`/``\1'\'''\''/g'
(注意:如果文件中已经有反勾号(`),它将无法正常工作,但如果没有,则应该这样做)

编辑: 通过简化消除了back tick bug,现在适用于所有情况:

cat file.txt | sed -e 's/"\([^"]*\)"/``\1'\'\''/g' | sed '/"/s/``/"/g' | sed '/"/s/'\'\''/"/g'
谨此陈辞:

{
    FS="\"" # set field separator to double quote
    if ((NF-1) % 2 == 0) { # if count of double quotes in line are even number
        res = $0 # save original line to res variable
        for (i = 1; i < NF; i++) { # for each double quote
            to = "``" # replace current occurency of double quote by ``
            if (i % 2 == 0) { # if its closes quote replace by ''
                to = "''"
            }
            # replace " by to in res and save result to res
            res = gensub("\"", to, 1, res)
        }
        print res # print resulted line
    } else {
        print # print original line when nothing to change
    }
}
cat file.txt                           # read file
| sed -e 's/"\([^"]*\)"/``\1'\'\''/g'  # initial replace
| sed '/"/s/``/"/g'                    # revert `` to " on lines with extra "
| sed '/"/s/'\'\''/"/g'                # revert '' to " on lines with extra "

这可能适合您:

sed 'h;s/"\([^"]*\)"/``\1''\'\''/g;/"/g' file
说明:

  • 复制原始行
    h
  • 替换成对的
    s/”\([^“]*\)“/`\1'\\\'\'\''/g
  • 检查是否存在奇数
    ,如果发现,则恢复到原始行
    /”/g

它并不漂亮,但我找到了一个
sed
1行bash脚本何时漂亮?我一直在关注这个
awk
解决方案(以及无数的迭代:P)2个多小时以来,老实说,我不认为它能做得更好。大量使用
gsub
来识别引号的数量,很好地使用
模运算符
,以及很好地使用
三元运算符
+1我知道这一点。:/。
cat file.txt | sed -e 's/"\([^"]*\)"/``\1'\'\''/g' | sed '/"/s/``/"/g' | sed '/"/s/'\'\''/"/g'
cat file.txt                           # read file
| sed -e 's/"\([^"]*\)"/``\1'\'\''/g'  # initial replace
| sed '/"/s/``/"/g'                    # revert `` to " on lines with extra "
| sed '/"/s/'\'\''/"/g'                # revert '' to " on lines with extra "
sed 'h;s/"\([^"]*\)"/``\1''\'\''/g;/"/g' file