Управляющий символ в awk-выходе

У меня есть следующий сценарий bash / awk , который делает то, что я хочу, за исключением того, что он добавляет символ управления, который я не знаю, что это значит.

 #!/usr/bin/env bash # Merge two cross section files from Resummino file1=filein1 file2=filein2 fileout=fileout awk '{ xs_nlo[$1," ",$2] += $4 xs_lo[$1," ",$2] += $3 } END { for (xs in xs_nlo){ print(xs, xs_lo[xs], xs_nlo[xs]) } } ' "${file1}" "${file2}" 

Возможный контент filein1 :

 100.000 500.000 7.878892e+00 1.027803e+01 100.000 1000.000 9.667085e+00 1.274467e+01 100.000 2000.000 1.029358e+01 1.361803e+01 100.000 5000.000 1.049836e+01 1.390297e+01 100.000 10000.000 1.052944e+01 1.394593e+01 

и аналогичные для filein2 , за исключением того, что последние два значения в каждой строке различаются. Предполагается, что awk скрипт будет добавлять третьи значения в каждой строке, считая, что первое и второе значения одинаковы. То же самое для четвертого значения.

Предполагается, что выходной файл имеет ту же структуру, что и входные файлы. В консоли выходной файл выглядит одинаково, но открывая его в vim , я вижу управляющий символ, который нелегко найти:

 100.000^\ ^\300.000 3.42 4.57283 

Что означает это ^\ ^\ и как я могу избавиться от него?

  • Печать наименьшего целого из файла с помощью специальной функции awk?
  • Добавьте десятичные знаки и выровняйте их вправо
  • Строки печати, если заданный столбец начинается с заглавной буквы
  • Я не могу найти процесс отправки почты?
  • AWK-Найти максимальное значение в строке и распечатать с заголовком
  • Разделить столбцы на основе шаблонов в полях
  • В AWK можно указать диапазон для работы?
  • Как увеличить колонку с помощью AWK
  • 3 Solutions collect form web for “Управляющий символ в awk-выходе”

    Источником проблемы является разделитель $1," ",$2 .

    Из документации:

    Многомерные массивы поддерживаются в awk посредством конкатенации индексов в одну строку. awk преобразует индексы в строки (см. Преобразование) и объединяет их вместе с разделителем между ними. Это создает единую строку, которая описывает значения отдельных индексов. Комбинированная строка используется как единый индекс в обычный одномерный массив. Используемый разделитель – это значение встроенной переменной SUBSEP


    SUBSEP
    Селектор индекса. Он имеет значение по умолчанию « \ 034 » и используется для разделения частей индексов многомерного массива. Таким образом, выражение «foo [" A "," B "] действительно обращается к foo [" A \ 034B "]


    Стандартный awk имитирует многомерные массивы, разделяя значения индексов запятыми. Значения объединяются в одну строку, разделяемую значением SUBSEP.
    Тот факт, что такой индекс был создан таким образом, не сохраняется; таким образом, изменение SUBSEP может иметь неожиданные последствия.

    Для второй части:

    Что означает это ^ \ ^ \ и как я могу избавиться от него?

    Еще один ответ уже объяснил, что запятая ( , ) в [$1," ",$2] становится SUBSEP. Thta – символ \034 (в восьмеричном) или 0x1C (в гексагоне).

    Этот символ также может быть записан в управляющем кодировании как ^\ .
    В этом причина того, что на выходе будут два ^\ .

    Решение состоит в том, чтобы вернуть (из awk-программы) управление тем, как создаются индексы массива. Самое простое решение состоит в том, чтобы объединить два поля ( $1 и $2 ) вместе, однако, что сделает равным эти два ключа массива (ни на одном конкретном языке):

     $1=abc $2=def $1$2 is abcdef $1=a $2=bcdef $1$2 is abcdef 

    Решение состоит в использовании символа, который не отображается в значениях $ 1 или $ 2. Пространство может показаться кандидатом, но FS (разделитель полей) является более общим решением, которое также может отделять поля при печати. Таким образом, этот скрипт работает для любого FS:

     #!/bin/bash # Merge two cross section files from Resummino file1=filein1 file2=filein2 fileout=fileout awk 'BEGIN{OFS=FS} { point = $1 FS $2 xs_nlo[ point ] += $4 xs_lo [ point ] += $3 } END { for (xs in xs_nlo){ print(xs, xs_lo[xs], xs_nlo[xs]) } } ' "${file1}" "${file2}" 

    Замена xs_nlo[$1," ",$2] с xs_nlo[$1" "$2] исправила его.

    Linux и Unix - лучшая ОС в мире.