J'utilise nawk
sur un fichier délimité par des tuyaux pour imprimer les champs comme index et clé où certains champs contiennent des espaces blancs, quand il n'y a pas d'espace blanc, tout fonctionne normalement, mais dans le cas d'espaces blancs en quelque sorte awk
le traite comme séparateur de champs et imprime cet o/p à la nouvelle ligne. Voir mon entrée ci-dessous:
Contribution:
a|b|c d e|1|2|3
a|b c|d|1|2|2 3
Production:
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
Production attendue:
Index=a|b|c d e
Key=1|2|3
Index=a|b c|d
Key=1|2|2 3
Bref pour deux index 2 index et 2 touches et garder les espaces blancs de base tels quels.
Je dois utiliser l'ensemble de code ci-dessous pour travailler sur chaque ligne car il y a trop de champs et des données énormes
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,"|");};'`
les réponses sont correctes lorsque vous utilisez un caractère spécial au lieu de l'espace, mais ce n'est pas correct sur les données d'entrée. alors je veux savoir si je peux conserver de l'espace dans ce processus.
Utilisation de 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
Plus lisible
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
Exemple
$ 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
Vous pouvez utiliser cette commande Perl
pour obtenir la sortie attendue:
$ 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
Je n'utiliserais pas [nmg]awk
pour cette tâche. Puisque votre script principal semble être écrit en bash
, remplacez simplement votre commande nawk
:
#!/bin/bash
Perl -ne 'print "Index=$1\nKey=$2\n" if /(.*?)[\s\|]([\|\d ]+)/' my_file
Notez que vous pouvez également supprimer la boucle créant $line
dans votre script d'origine.
Créez un fichier et enregistrez-y le script 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"
}
Enregistrez le fichier, exécutez Sudo chmod +x awk-script-name.awk
, et exécutez-le avec le fichier de test comme ceci:
$ 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