Как изменить файл, если файл содержит числа, начинающиеся с «+1»

Я передаю базу данных Android SMS на свой iPhone вручную без восстановления. Из-за числового формата +1562 ... iPhone не распознает формат и создает новую текстовую цепочку.

Я пытаюсь изменить +15629876543 на 5629876543 и +17114747474 на 7114747474 и т. Д.

Есть еще тысячи чисел различного размера. Любой другой номер, имеющий более или менее 10 цифр, должен быть нетронутым.

Это, кажется, шаг в правильном направлении:

grep -P '(?<!\d)\d{4}(?!\d)' file

получено из Как выполнить поиск для групп из n цифр, но не более n?

Вот пример файла XML ( РЕДАКТИРОВАТЬ: я добавил корневой элемент с именем <root>, чтобы XML был правильно сформирован ).

<root>
    <sms>
        <address>+15629876543</address>
        <date>1554966601000</date>
        <type>1</type>
        <body> Yea, should be true. </body>
        <mmsReaded>1</mmsReaded>
        <attachments />
    </sms>
    <sms>
        <isMms>1</isMms>
        <date>1554968044000</date>
        <type>2</type>
        <mmsMsgBox>2</mmsMsgBox>
        <mmsReaded>1</mmsReaded>
        <attachments>
            <attachment>
                <type>image/jpeg</type>
                <body></body>
                <name>Screenshot_20190411-002704_Flud.jpg</name>
            </attachment>
        </attachments>
    </sms>
    <sms>
        <isMms>0</isMms>
        <address>+15621234567</address>
        <date>1554968778000</date>
        <type>1</type>
        <isMms>0</isMms>
        <address>+17141234534</address>
        <date>1558919932000</date>
        <type>1</type>
        <body>:)</body>
        <mmsReaded>1</mmsReaded>
        <attachments />
    </sms>
    <sms>
        <isMms>0</isMms>
        <address>+17141234567</address>
        <date>1558927846000</date>
        <type>1</type>
        <body>It&apos;s so</body>
        <mmsReaded>1</mmsReaded>
        <attachments />
        <isMms>0</isMms>
        <address>+17145757575</address>
        <date>1543704644000</date>
        <type>1</type>
        <body>Hey</body>
        <mmsReaded>1</mmsReaded>
        <attachments />
    </sms>
    <sms>
        <isMms>0</isMms>
        <date>1543704676000</date>
        <type>2</type>
        <body>More text</body>
        <mmsReaded>1</mmsReaded>
        <attachments />
    </sms>
    <sms>
        <isMms>0</isMms>
        <address>+17142323232</address>
        <date>1543704736000</date>
        <type>1</type>
        <body>Lol not even</body>
        <mmsReaded>1</mmsReaded>
        <attachments />
    </sms>
    <sms>
        <isMms>0</isMms>
        <address>+17141010101</address>
        <date>1543704748000</date>
        <type>1</type>
        <body>You do</body>
        <mmsReaded>1</mmsReaded>
        <attachments />
    </sms>
</root>
3
задан 3 October 2019 в 06:49

2 ответа

Будьте очень осторожны, чтобы использование sed отредактировало XML-файлы. (Это опасно).

, Но можно легко использовать процессор XSLT-1.0 как xsltproc или Saxon для удаления продвижения +1 строка от <address> элемент. Так используйте следующий файл

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output omit-xml-declaration="yes" /> 
  <xsl:output method="xml" indent="yes" /> 

    <!-- Identity template -->
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*" />
        </xsl:copy>
    </xsl:template>  

    <xsl:template match="sms/address[starts-with(.,'+1')]">
        <xsl:copy>
            <xsl:value-of select="substring(.,3)"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

XSLT со своим XML, и результат (с XML от Вашего вопроса):

<root>
    <sms>
        <address>5629876543</address>
        <date>1554966601000</date>
        <type>1</type>
        <body> Yea, should be true. </body>
        <mmsReaded>1</mmsReaded>
        <attachments/>
    </sms>
    <sms>
        <isMms>1</isMms>
        <date>1554968044000</date>
        <type>2</type>
        <mmsMsgBox>2</mmsMsgBox>
        <mmsReaded>1</mmsReaded>
        <attachments>
            <attachment>
                <type>image/jpeg</type>
                <body/>
                <name>Screenshot_20190411-002704_Flud.jpg</name>
            </attachment>
        </attachments>
    </sms>
    <sms>
        <isMms>0</isMms>
        <address>5621234567</address>
        <date>1554968778000</date>
        <type>1</type>
        <isMms>0</isMms>
        <address>7141234534</address>
        <date>1558919932000</date>
        <type>1</type>
        <body>:)</body>
        <mmsReaded>1</mmsReaded>
        <attachments/>
    </sms>
    <sms>
        <isMms>0</isMms>
        <address>7141234567</address>
        <date>1558927846000</date>
        <type>1</type>
        <body>It's so</body>
        <mmsReaded>1</mmsReaded>
        <attachments/>
        <isMms>0</isMms>
        <address>7145757575</address>
        <date>1543704644000</date>
        <type>1</type>
        <body>Hey</body>
        <mmsReaded>1</mmsReaded>
        <attachments/>
    </sms>
    <sms>
        <isMms>0</isMms>
        <date>1543704676000</date>
        <type>2</type>
        <body>More text</body>
        <mmsReaded>1</mmsReaded>
        <attachments/>
    </sms>
    <sms>
        <isMms>0</isMms>
        <address>7142323232</address>
        <date>1543704736000</date>
        <type>1</type>
        <body>Lol not even</body>
        <mmsReaded>1</mmsReaded>
        <attachments/>
    </sms>
    <sms>
        <isMms>0</isMms>
        <address>7141010101</address>
        <date>1543704748000</date>
        <type>1</type>
        <body>You do</body>
        <mmsReaded>1</mmsReaded>
        <attachments/>
    </sms>
</root>

Это должно быть так желаемо.

1
ответ дан 23 October 2019 в 09:33

Да, необходимо обычно избегать использования регулярных выражений для парсинга структурированных данных. Но это - довольно простой случай, если Вы - 100% что все случаи + сопровождаемый 11 цифр являются допустимыми целями. Можно сказать sed только удалить + если это сопровождается 11 числами (я предполагаю, что Вы имели в виду 11 не 10, так как Вы имеете 11 в Ваших данных):

sed -E 's/\+([0-9]{11}[^0-9]*)\b/\1/' file.xml 

-E включает расширенные регулярные выражения, которые дают упрощенный синтаксис и способность использовать {N} означать "соответствие N времена". Таким образом, здесь, мы соответствуем a + (этого нужно оставить как \+ так как иначе это означает "соответствие 1 или более"), который сопровождается точно 11 числами, затем 0 или больше нечисел до первой границы слова (\b).

Все соответствие кроме + получен в круглых скобках, таким образом, \1, замена, все кроме +.


Немного более безопасный подход, так как все Ваши целевые числа, кажется, находятся в address теги, был бы:

sed -E 's|<address>\+([0-9]{11})<\/address>|<address>\1</address>|' file.xml 

Или даже, если о Вашей проблеме можно вновь заявить как, "удаляют все + от строк, где первая строка непространства <address>", Вы могли сделать:

sed -E '/<address>+/{s/\+//}' file.xml
0
ответ дан 23 October 2019 в 09:33

Другие вопросы по тегам:

Похожие вопросы: