сохраните пробелы в полях при использовании awk

Я использую nawk на разграниченном файле канала для печати полей как индекса и ключа, где некоторые поля содержат пробел когда нет никакого пробела, все работает нормальное, но в случае пробелов так или иначе awk обработки это как разделитель полей и печать этот o/p к новой строке. Посмотрите мой вход ниже:

Вход:

a|b|c d e|1|2|3
a|b c|d|1|2|2 3

Вывод:

Index=a|b|c 
Key=1|2|3
Index=d
Key=<null>
Index=e
Key=<null>
Index=a|b
Key=1|2|2
Index=c|d
Key=3

Ожидаемый вывод:

Index=a|b|c d e
Key=1|2|3
Index=a|b c|d
Key=1|2|2 3

Короче говоря для двух рекордных 2 Индексов и 2 ключей и сохраняют основные пробелы как есть.

Я должен использовать ниже набора кода для работы над каждой строкой, потому что существует слишком много полей и наличия огромных данных

    index=`echo "$line" | nawk -F '|' '
    function select_from(from,to,delim)
    {
            if (to < from) { return; };
            for (i=from;i<=to;i++)
            {
                            if (NF < i) { break;};
                            if (i < to)
                            {
                                    printf("%s%s",i,delim);
                            } else {
                                    printf("%s",i);
                            };
            };
    }
    {select_from(11,48,"|");};'`

ответ корректен при использовании некоторого специального символа вместо пространства, но это не корректно на входных данных. поэтому хочу знать, могу ли я сохранить пространство в этом процессе.

1
задан 24 June 2015 в 01:28

3 ответа

Используя awk

from=1; to=3; delimiter="|"; awk -F"$delimiter" -v from="$from" -v to="$to" '!/^[[:blank:]]*$/ {printf "Index="; for(i=from; i<=to; i++) {printf $i; if(i<to) {printf "|"};} printf "\n"; printf "Key="; for(i=to+1; i<=NF; i++) {printf $i; if(i<NF) {printf "|"};} printf "\n"}' foo

[еще 117] читаемый

from=1; to=3; delimiter="|";
awk -F"$delimiter" -v from="$from" -v to="$to" '!/^[[:blank:]]*$/ {
    printf "Index=";
    for(i=from; i<=to; i++) {
        printf $i;
        if(i<to) {
            printf "|"
        };
    }
    printf "\n";
    printf "Key=";
    for(i=to+1; i<=NF; i++) {
        printf $i;
        if(i<NF) {
            printf "|"
        };
    }
    printf "\n"
}' foo
<час>

Пример

$ cat foo
a|b|c d e|1|2|3
a|b c|d|1|2|2 3

$ from=1; to=3; delimiter="|"; awk -F"$delimiter" -v from="$from" -v to="$to" '!/^[[:blank:]]*$/ {printf "Index="; for(i=from; i<=to; i++) {printf $i; if(i<to) {printf "|"};} printf "\n"; printf "Key="; for(i=to+1; i<=NF; i++) {printf $i; if(i<NF) {printf "|"};} printf "\n"}' foo
Index=a|b|c d e
Key=1|2|3
Index=a|b c|d
Key=1|2|2 3
2
ответ дан 10 November 2019 в 09:17

Можно использовать этот perl команда для получения ожидаемого вывода:

$ perl -ne 'print "Index=$1\nKey=$2\n" if /(.*?)[\s\|]([\|\d ]+)/' my_file
Index=a|b|c d e
Key=1|2|3
Index=a|b c|d
Key=1|2|2 3

я не использовал бы [nmg]awk для той задачи. Так как Ваш основной сценарий, кажется, записан в bash, просто заменяет Ваш nawk команда:

#!/bin/bash

perl -ne 'print "Index=$1\nKey=$2\n" if /(.*?)[\s\|]([\|\d ]+)/' my_file

Примечание, что можно также удалить цикл, создающий $line в исходном сценарии.

1
ответ дан 10 November 2019 в 09:17

Создайте файл и сохраните awk рев сценария в него:

#!/usr/bin/awk -f

BEGIN { FS="|";} 
{ 
  printf"Index:";
  for(i=1;i<=NF;i++) {
       if ($i~/[[:alpha:]]/ && $(i+1)!~/[[:digit:]]/) { printf $i"|";
    }
    else if ($i~/[[:alpha:]]/ && $(i+1)~/[[:digit:]]/) {
    print $i
    }
  }

printf "\n"
} 


{ 
  printf"Key=:";
  for(i=1;i<=NF;i++) {
     if ($i~/[[:digit:]]/ && $(i+1)~/[[:digit:]]/) printf $i"|" ;
    else if ($i~/[[:digit:]]$/)  printf $i;

    }
printf "\n"
}  

Сохранили файл, работают sudo chmod +x awk-script-name.awk и выполняют его с тестовым файлом как так:

$ cat testfile.txt                                                                                                                    
a|b|c d e|1|2|3
a|b c|d|1|2|2 3

$ key-index-script.awk testfile.txt                                                                                                   
Index:a|b|c d e

Key=:1|2|3
Index:a|b c|d

Key=:1|2|2 3
0
ответ дан 10 November 2019 в 09:17

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

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