Заполнение для файла, содержащего русские кириллические символы в файле, не работает - один русский символ считается за 2 байта - PullRequest
0 голосов
/ 23 октября 2019

Я пытаюсь создать файл с фиксированной длиной столбца в Unix. Файл содержит русские кириллические символы, и эти символы интерпретируются не так, как обычные 1-байтовые символы.

Я использую приведенный ниже скрипт для изменения файла (разделитель столбцов - @ - @, а разделитель строк -\ r \ n):

input_file=$1
output_file=$2

awk -F '@-@' '{printf("%-200s%-200s%-200s%-200s%-200s%-200s%-200s%-200s\r\n", $1, $2, $3, $4, $5, $6, $7, $8)}' $input_file > $output_file

Для столбцов с нормальными символами выходной файл содержит правильно 200 символов столбцов, но для столбца с 30 кириллическими символами выходной столбец содержит только 170 символов. Таким образом, строки в файле не будут иметь одинаковую длину, потому что кириллические символы занимают 2 байта, и код будет интерпретировать байты, а не символы.

Пример: НИКОЛАЕВНА имеет 10 символов, но скриптвычисляется как 20, поскольку он занимает 20 байтов.

Один пример входного файла:

НИКОЛАЕВНА@-@russ@-@12345@-@asklle@-@НИКОЛАЕВНА@-@454@-@111@-@asdfg

Не могли бы вы предложить способ создания отступа, чтобы все строки имели одинаковое числосимволов?

Спасибо!

Ответы [ 3 ]

0 голосов
/ 23 октября 2019

Я не верю, что awk может сделать это, но gawk должен обрабатывать это по умолчанию, если ваш языковой стандарт не установлен на "C". Например, LC_ALL=en_US.UTF-8 должен обеспечивать ожидаемое поведение с использованием gawk.

0 голосов
/ 24 октября 2019

Попробуйте следующий awk скрипт:

script.awk

BEGIN {FS="@-@"; # field separator is '@-@'
    h="          "; # length(h) = 10
    h=h h h h h h h h h h; # length(h) = 100
    h=h h; # length(h) = 200
}
{
    for (i = 1; i <= 8; i++) {
        #length is character based function
        head = substr(h,1,(length(h)-length($i))); # cut alignment head to the correct length
        printf("%s%s", head, $i); # output the current aligned field
    }
    print;
}
0 голосов
/ 23 октября 2019

Я предлагаю вам использовать gawk символьную строковую функцию substr, чтобы обрезать ваши строки. Стандартная функция форматирования ширины gawk printf является символьной. проверьте, используете ли вы последнюю версию gawk.

Чтобы обрезать все поля до 200 символов:

for (i = 1; i <= NF; i++) $i = substr($i,1,200);

Итак, ваш скрипт должен быть:

awk -F '@-@' '{for(i=1;i<=NF;i++)$i=substr($i,1,200);printf("%-200s%-200s%-200s%-200s%-200s%-200s%-200s%-200s\r\n", $1, $2, $3, $4, $5, $6, $7, $8)}' $input_file > $output_file

Или более кратко:

script.awk

{
    for (i = 1; i <= 8; i++) {
        $i = substr($i,1,200);
        printf("%-200s", $i);
    }
    print;
}
...