Я хочу удалить 1-й символ из каждой строки как специальный и преобразовать файл в ; файл с разделителями точками с запятой

grep Вероятно, он выходит после первого совпадения. Это xinput, который все еще работает :, он только замечает, что канал закрыт, когда в следующий раз пытается что-то вывести.

Например, здесь только первый pgrep находит работающий grepпроцесс, но сон слева -все равно происходит.

$ ( pgrep grep >&2; echo xxx; pgrep grep >&2; sleep 3; echo yyy ) |grep -m1 xxx
29149
xxx
2
12.08.2020, 16:21
4 ответа

Поскольку â, которое вы видите, почти наверняка является проблемой кодировки, и предполагается, что все ваши строки должны начинаться с заглавной буквы, вы можете попробовать это:

LC_ALL=C sed 's/^[^A-Z]*//; s/   */;/g' FILE1.txt > FILE2

Это запустит команду, используя локаль C, которая должна гарантировать, что любой символ, которым является ваш â, не включен в диапазон A -Z. Затем команда sed просто удаляет все символы, не входящие в диапазон A -Z, с начала каждой строки, а затем преобразует все вхождения двух или более пробелов в ;.

2
18.03.2021, 23:13

Я думаю, что проблема может быть связана с кодировкой символов, попробуйте отобразить FILE1.txtв обоих env с помощью

hexdump -C FILE1.txt

Он может быть закодирован как E -ascii или UTF -8 (см.https://en.wikipedia.org/wiki/%C3%82#Character_mappings)

Чтобы решить вашу проблему, вы можете попробовать сопоставить обе кодировки:

        â in UTF-8                     â in other encoding
        |                              |
        v                              v
sed 's/\xc3\xa2//' FILE1.txt | sed 's/\xE2//' > FILE2.txt

Другим решением может быть преобразование файла в известную кодировку перед его обработкой.

Может быть опасно не тестировать кодировку PROD.

4
18.03.2021, 23:13

попробуй

sed 's/^â//; s/   */;/g' FILE1.txt > FILE2.txt

И голосуйте против, если это не работает для вас

2
18.03.2021, 23:13

Чтобы удалить первый символ каждой строки, он должен быть:

cut -c2- # not with the GNU implementation which is currently not multi-byte aware
sed 's/^.//'
awk '{print substr($0, 2)}' # note the 2 instead of 1 as offsets are 1-based
                            # not with mawk or other non-multi-byte aware awk
                            # implementations.

Однако имейте в виду, что для того, чтобы .соответствовал этому символу âи substr()работал правильно, этот âдолжен быть закодирован в соответствии с кодировкой локали (, см. выводlocale charmap).

Чтобы удалить первый символ и заменить все последовательности пробелов на ;, вы можете сделать либо:

sed 's/^.//;s/[[:space:]]\{1,\}/;/g'

Или:

awk -v OFS=';' '{$0 = substr($0, 2); $1 = $1; print}'

(хотя имейте в виду, что последний не будет включать завершающий ;для строк, которые заканчиваются пробелами, а список пробелов, которые считаются разделителями, зависит от реализации awkи локали ).

Также имейте в виду, чтоâ(U+00E2 )закодирован как байт 0xe2 в кодировке iso8859 -1 (, также известной как latin1и некоторых других однобайтовых кодировках ). И этот байт 0xe2 также является первым байтом кодирования числа из 3 -байтов UTF -8 символов, среди которых есть несколько пробелов Unicode (, таких как интервал от U+2000 до U+200B. символы ).

Таким образом, если вы видите â, отображаемый в терминале latin1, возможно, ввод на самом деле содержит U+2002 (EN SPACE ), например, закодированный в UTF -8 (. ] 0xe2 0x80 0x82 ), и ваш терминал отобразит это 0xe2как âи ничего не покажет для 0x80 и 0x82, которые не находятся в latin1.

Чтобы избавиться от этого EN SPACE, вам нужно либо удалить 1 символ из локали UTF -8, либо удалить 3 символа из одной -байтовой локали (, например, с использованием latin1 или C локаль ).

2
18.03.2021, 23:13

Теги

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