Замена кавычек на «` »и« » - PullRequest
2 голосов
/ 23 января 2012

У меня есть документ, содержащий много " отметок, но я хочу преобразовать его для использования в 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)

Мои предложения никогда не разбиваются на строки, поэтому нет необходимости проверять несколько строк.

Есть несколько кавычек с одинарными кавычками, поэтому я могу изменить их вручную.

Как я могу преобразовать их?

Ответы [ 4 ]

3 голосов
/ 23 января 2012

Это мой однострочный текст, который работает для меня:

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

И есть длинная версия этого однострочного с комментариями:

{
    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
    }
}

Вы можете запустить этот скрипт:

awk -f replace-quotes.awk input.txt >output.txt
2 голосов
/ 23 января 2012

Это может работать для вас:

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

Пояснение:

  • Сделайте копию оригинальной строки h
  • Заменить пары " s/"\([^"]*\)"/``\1''\'\''/g
  • Проверить нечетное " и, если оно найдено, вернуться к исходной строке /"/g
2 голосов
/ 23 января 2012

Вот мой однострочник, использующий повторяющиеся sed:

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

(примечание: он не будет работать правильно, если в файле уже есть обратные тики (`), но в противном случаесделать трюк)

РЕДАКТИРОВАТЬ:

Удалена ошибка обратной галочки путем упрощения, теперь работает для всех случаев:

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 "
2 голосов
/ 23 января 2012

Использование awk

awk '{n=gsub("\"","&")}!(n%2){while(n--){n%2?Q=q:Q="`";sub("\"",Q Q)}}1' q=\' in

Пояснение

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 '/^\([^"]*"[^"]*"[^"]*\)*$/s/"\([^"]*\)"/``\1'\'\''/g' in
...