Как я могу использовать Sed с символом Unicode - PullRequest
0 голосов
/ 04 октября 2019
function change() {
  for i in {0..28}
  do
    echo ",${cryp_data_letter[$i]}" "${org_data[$i]}"
    sed -i "s/,${cryp_data_letter[$i]}/${org_data[$i]}/g" "./temp.txt"
    #cat "./temp.txt"
  done
}

У меня есть функция, которая изменяет некоторый символ в файле temp.txt по специальному правилу, но некоторые символы, такие как ı, ğ, ö и т. Д., Меняются с пустой строкой. Я полагаю, что причиной проблемы является UTF-8, так как я могу применить sed с Unicode? или любое другое предложение для -> "sed -i" s /, $ {cryp_data_letter [$ i]} / $ {org_data [$ i]} / g "" ./temp.txt ""

Вот этот файл temp.txt:

abc ğhıi
def
jkl
oöpr
uü vy z
çgm ns
şt

и вывод:

IDK ,ğS,ıT
NMY
BOÜ
G,öHÇ
P,ü ÖF ,
,çUŞ ZĞ
,şV

Кстати, в процессе возврата я поменяю все буквы строчными буквами и поставлю «,»перед всей буквой, поэтому она станет перед sed:

,a,b,c ,ğ,h,ı,i
,d,e,f
,j,k,l
,o,ö,p,r
,u,ü ,v,y ,z
,ç,g,m ,n,s
,ş,t

LOCALE:

LANG=en_US.UTF-8
LANGUAGE=en_US:en
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC=tr_TR.UTF-8
LC_TIME=tr_TR.UTF-8
LC_COLLATE="en_US.UTF-8"
LC_MONETARY=tr_TR.UTF-8
LC_MESSAGES="en_US.UTF-8"
LC_PAPER=tr_TR.UTF-8
LC_NAME=tr_TR.UTF-8
LC_ADDRESS=tr_TR.UTF-8
LC_TELEPHONE=tr_TR.UTF-8
LC_MEASUREMENT=tr_TR.UTF-8
LC_IDENTIFICATION=tr_TR.UTF-8
LC_ALL=

Ответы [ 2 ]

1 голос
/ 04 октября 2019

Здесь есть несколько проблем, каждая из которых может быть причиной отдельной проблемы или комбинации.

  • Мы не можем знать, какой набор символов и кодировку вы используете. Ваш языковой стандарт правильно настроен для UTF-8, но ваш терминал и другое программное обеспечение могут работать некорректно. Возможно, смотрите также страницу информации о тегах Stack Overflow character-encoding для получения дополнительной информации и диагностики.
  • Даже если ваша система и утилиты, как правило, совместимы с UTF-8, нет гарантии, что ваша sed есть. Многие sed варианты до сих пор не обращают внимания на Unicode, и нет стабильного предложения о том, каким именно должно быть поведение. Иногда имеет смысл переключиться на другой язык;многие тривиальные сценарии sed могут быть легко перенесены для запуска в perl -CSD -p с небольшими изменениями или без изменений.
  • Даже если все остальное работает правильно, Unicode предоставляет несколько способов представления множества акцентированных символов. Если ваши данные содержат ö в виде единой кодовой точки U + 00E6, но ваш сценарий содержит соответствующую разложенную последовательность или наоборот, ваш сценарий sed (вероятно) не заменит альтернативное представление. Посмотрите на нормализацию Юникода.

Если это не удастся, если вторая точка достаточна, может сработать следующее:

perl -CSD -pi~ e 'tr/AEİR...FJ/ABCÇ...YZ/' ./temp.txt

Обратите внимание на параметр -i~ длявыполнить редактирование на месте, но сохранить файл резервной копии. У меня мало уверенности, что это сработает сразу, без каких-либо изменений и, возможно, разъяснений с вашей стороны.

1 голос
/ 04 октября 2019

Извините за отсутствие ответа, но я не могу воспроизвести вашу проблему.

Вот ваш код в полностью автономном скрипте (пожалуйста, сделайте это самостоятельно в следующий раз):

#!/bin/bash

if [[ ö != $'\xC3\xB6' ]]
then
  echo "You didn't save this file as UTF-8"
  exit 1
fi

function change() {
  for i in {0..28}
  do
#    echo ",${cryp_data_letter[$i]}" "${org_data[$i]}"
    sed -i "s/,${cryp_data_letter[$i]}/${org_data[$i]}/g" "./temp.txt"
    #cat "./temp.txt"
  done
}

# Shift all characters one letter ahead in the alphabet
cryp_data_letter=({a..z} ğ ö ı)
org_data=({b..z} ğ ö ı a)

# Create the file as you say it is before the sed
cat > temp.txt << "EOF"
,a,b,c ,ğ,h,ı,i
,d,e,f
,j,k,l
,o,ö,p,r
,u,ü ,v,y ,z
,ç,g,m ,n,s
,ş,t
EOF

change

cat temp.txt

Когда я запускаю ./testscript, я получаю следующий вывод:

bcd öiaj
efg
klm
pıqs
v,ü wz ğ
,çhn ot
,şu

Как видите, буквы, включающие ö и ğ, заменяются и вставляются очень хорошо.

...