Я использую 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,"|");};'`
ответ корректен при использовании некоторого специального символа вместо пространства, но это не корректно на входных данных. поэтому хочу знать, могу ли я сохранить пространство в этом процессе.
Используя 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
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
Можно использовать этот 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
в исходном сценарии.
Создайте файл и сохраните 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