3
votes

Comment récupérer uniquement les entrées impaires d'un fichier à l'aide de la commande awk dans un fichier délimité par un tube?

Besoin de récupérer uniquement les colonnes impaires d'un fichier délimité par un tube.

1|WORK
2|OFFICE
3|HOME
4|PERSONAL

SORTIE ATTENDUE

SOURCE_FILE
1|ABC|WORK|1234
2|DEF|OFFICE|5678
3|GHI|HOME|9012
4|JKL|PERSONAL|3456

J'essaie d'utiliser awk -F '|' '{pour (i = 1; i > delimt.txt , mais il supprime les valeurs et non la position.


0 commentaires

3 Réponses :


2
votes

1ère solution: Pourriez-vous essayer de suivre.

1|WORK
2|OFFICE
3|HOME
4|PERSONAL


2ème solution: Sans utiliser de variable et devrait être plus rapide que la 1ère solution, essayez de suivre.

awk '
BEGIN{
  FS=OFS="|"
}
{
  for(i=1;i<=NF;i+=2){
    printf("%s%s",$i,(i==NF || i==(NF-1)) && i%2!=0?ORS:OFS)
  }
}
'   Input_file

OU (en ajoutant une forme non-une ligne de la solution ci-dessus ):

awk 'BEGIN{FS=OFS="|"} {for(i=1;i<=NF;i+=2){printf("%s%s",$i,(i==NF ||i==(NF-1)) && i%2!=0?ORS:OFS)}}' Input_file

La sortie sera la suivante.

 awk 'BEGIN{FS=OFS="|"} {for(i=1;i<=NF;i+=2){val=(val?val OFS:"") $i};print val;val=""}' Input_file


7 commentaires

Merci Ravinder Singh. Cela fonctionne parfaitement comme prévu.


@PraveenP, votre bienvenue, heureux d'aider, continuez à apprendre et continuez à partager sur ce grand site SO.


Pourquoi ne pas utiliser aussi NF> 1?


@ClaesWikner, désolé, je ne l'ai pas trouvé exactement où vous demandez que cette condition soit placée?


@ RavinderSingh13. Comme dans l'exemple OP, l'en-tête est supprimé, vous pouvez placer devant votre "{for", juste mes deux cents.


@PraveenP, vous demander de bien vouloir mentionner la raison de la désélection de la bonne réponse, pourrait essayer de l'améliorer.


@ RavinderSingh13 La désélection s'est produite sans le savoir, désolé pour cela. J'ai utilisé votre code et cela a fonctionné comme prévu.



1
votes

Un autre awk

$ cat praveen.txt
1|ABC|WORK|1234
2|DEF|OFFICE|5678
3|GHI|HOME|9012
4|JKL|PERSONAL|3456

$ awk -F"|" -v OFS="|" ' { for(i=1;i<NF;i+=2) { printf("%s%s",s,$i);s="|"; } print "";s=""  } ' praveen.txt
1|WORK
2|OFFICE
3|HOME
4|PERSONAL

$

avec des entrées données

 awk -F"|" -v OFS="|" ' { for(i=1;i<NF;i+=2) { printf("%s%s",s,$i);s="|"; } print "";s=""  } '


1 commentaires

Merci beaucoup pour la réponse. Facilement compréhensible. J'ai appris un moyen de mieux le faire.



1
votes

Vous pouvez également le faire avec coreutils:

1|WORK
2|OFFICE
3|HOME
4|PERSONAL

Sortie:

cols=$(head -n1 infile | tr '|' '\n' | wc -l)
cut -d'|' -f$(seq -s, 1 2 $cols) infile


1 commentaires

Vraiment une bonne suggestion. Je n'ai donné qu'un échantillon d'entrées en question, mais le fichier réel avait n nombre d'entrées. Donc, fournir des chiffres ne semble pas une bonne idée dans mon cas.