Используя sed для замены прописных букв на строчные, пробел для подчеркивания и создания XML-файла с результатами - PullRequest
0 голосов
/ 05 июня 2018

Извиняюсь заранее, если это указано неверно, поскольку я искал, но не смог найти способ sed + echo при использовании while loop для чтения файла.

У меня есть ранее.TXT-файл, который выглядит так:

The sun is Shining
The moon is dull tonight
I Feel Like Dancing

, и мне нужно, чтобы он выглядел так:

<message>
        <source>the_sun_is_shinig</source>
        <translation>The sun is Shining</translation>
</message>
<message>
        <source>the_moon_is_dull_tonight</source>
        <translation>The moon is dull tonight</translation>
</message>
<message>
        <source>i_feel_like_dancing</source>
        <translation>I Feel Like Dancing</translation>
</message>

Это то, что у меня так далеко ...

#!/bin/bash

echo -n "" > json.xml
while IFS='' read -r line || [[ -n "$line" ]]; do
   sed -e 's/\(.*\)/\L\1/; s/ /_/g' < "$line" > temp.txt
   sourceline="$(cat temp.txt)"
   echo "<message>" >> json.xml
   echo -e "\t<source>${sourceline}<source>" >> json.xml
   echo -e "\t<translation>${line}<translation>" >> json.xml
   echo "<message>" >> json.xml
done < "$1"
rm -f temp.txt
cat json.xml
exit

Но это не удалось

cp@0000 ~/work $ bash .language_file_fixer.sh before.txt
.language_file_fixer.sh: line 5: The sun is Shining: No such file or directory
cat: temp.txt: No such file or directory
.language_file_fixer.sh: line 5: The moon is dull tonight: No such file or directory
cat: temp.txt: No such file or directory
.language_file_fixer.sh: line 5: I Feel Like Dancing: No such file or directory
cat: temp.txt: No such file or directory
<message>
        <source><source>
        <translation>The sun is Shining<translation>
<message>
<message>
        <source><source>
        <translation>The moon is dull tonight<translation>
<message>
<message>
        <source><source>
        <translation>I Feel Like Dancing<translation>
<message>

Как мне передать $ line в sed?

Ответы [ 3 ]

0 голосов
/ 05 июня 2018

Вы лаете не на то дерево.Это работа для awk, а не для какого-то медленного, хрупкого, запутанного цикла оболочки, вызывающего sed.

$ cat tst.awk
{
    print  "<message>"
    printf "\t<source>%s</source>\n", gensub(/[[:space:]]/,"_","g",tolower($0))
    printf "\t<translation>%s</translation>\n", $0
    print "</message>"
}

$ awk -f tst.awk file
<message>
        <source>the_sun_is_shining</source>
        <translation>The sun is Shining</translation>
</message>
<message>
        <source>the_moon_is_dull_tonight</source>
        <translation>The moon is dull tonight</translation>
</message>
<message>
        <source>i_feel_like_dancing</source>
        <translation>I Feel Like Dancing</translation>
</message>

В приведенном выше примере GNU awk используется для gensub (), а для других awk вы бы использовали переменную и gsub.().

0 голосов
/ 05 июня 2018

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

sed -e 'i<message>' -e 'h;y/ /_/;s/.*/\L\t<source>&<\/source>/p;x;s/.*/\t<translation>&<\/translation>/;a<\/message>' file

Вставить тег message, скопировать строку ввода, перевести пробелы в подчеркивания, вывести строку, окруженную тегами source, и преобразоватьв нижнем регистре.Извлеките исходную линию и окружите ее тегами translation и добавьте закрывающий тег message.

0 голосов
/ 05 июня 2018

Вы можете сделать это полностью с GNU sed (sed читает входной файл построчно и читает ваши инструкции для обработки каждой строки):

Ввод:

$ more messages 
The sun is Shining
The moon is dull tonight
I Feel Like Dancing

Вывод:

$ sed -n 'h;s/\(.*\)/\L\1\E/;s/ /_/g;s/\(.*\)/<message>\n\t<source>\1<\/source>/p;x;s/\(.*\)/\t<translation>\1<\/translation>\n<\/message>/p' messages 
<message>
        <source>the_sun_is_shining</source>
        <translation>The sun is Shining</translation>
</message>
<message>
        <source>the_moon_is_dull_tonight</source>
        <translation>The moon is dull tonight</translation>
</message>
<message>
        <source>i_feel_like_dancing</source>
        <translation>I Feel Like Dancing</translation>
</message>

Пояснения:

Для целей чтения позвольте мне разбить команду на несколько строк:

sed -n 'h; \
s/\(.*\)/\L\1\E/;  \
s/ /_/g; \
s/\(.*\)/<message>\n\t<source>\1<\/source>/p; \
x; \
s/\(.*\)/\t<translation>\1<\/translation>\n<\/message>/p' messages
  • Проверка выполнена с опцией GNU sed 4.2.2
  • -n для отключения режима автопечати
  • h для сохранения строки в буфере удержания(все приведенные ниже операции будут выполняться с буфером шаблонов)
  • s/\(.*\)/\L\1\E/g используется для преобразования всей строки в нижний регистр
  • s/ /_/g используется для преобразования пробелов в подчеркиваниях
  • s/\(.*\)/<message>\n\t<source>\1<\/source>/p используется для добавления начального тега <message> с последующим переводом строки, табуляции и <source> <\/source>, окружающих преобразованное сообщение
  • p используется для его печати
  • x используется для обмена двумя буферами, после выполнения этой операции буфер шаблона содержит строку как есть
  • s/\(.*\)/\t<translation>\1<\/translation>\n<\/message>/p используется для добавления тегов <translation> и окончания тега <\/message> перед печатью результата с помощью p
...