imprimer tous les champs sauf certains dans awk

j'ai un gros fichier avec des centaines de colonnes que je veux supprimer uniquement les troisième et quatrième colonnes de et imprimer le reste dans un fichier. Mon idée initiale était de faire un script awk awk '{print , , for (i=; i <= NF; i++) print $i }' file > outfile. Toutefois, ce code ne fonctionne pas.

j'ai ensuite essayé:

awk '{for(i = 1; i<=NF; i++)
if(i == 3 || i == 4) continue
else
print($i)}' file > outfile

Mais cela imprimée tout dans un champ. Il serait possible de diviser en deux scripts et de les combiner avec d'unix paste mais cela semble être quelque chose qui devrait être en mesure d'être fait en une seule ligne.

8
demandé sur Stedy 2011-06-23 21:49:08

6 réponses

Votre premier essai était assez proche. En le modifiant pour utiliser printf et y compris les séparateurs de champ a fonctionné pour moi:

awk '{printf FS; for (i=5; i <= NF; i++) printf FS$i; print NL }'
11
répondu Carl Norum 2011-06-23 17:57:49

dites que vous avez un onglet fichier délimité qui ressemble à ce qui suit:

temp.txt

champ1 champ2 champ3 field4 field5 field6

champ1 champ2 champ3 field4 field5 field6

champ1 champ2 champ3 field4 field5 field6

l'exécution de ce qui suit supprimera les champs 3 et 4 et la sortie à la fin de la ligne.

awk '{print "\t""\t"substr(, index(,))}' temp.txt

champ1 champ2 field5 field6

champ1 champ2 field5 field6

champ1 champ2 field5 field6

mon(mes) exemple (s) imprimer à stdout. > newFile va envoyer stdout à newFile et >> newFile ajouter à newFile.

vous pouvez donc utiliser ce qui suit:

awk '{print "\t""\t"substr(, index(,))}' temp.txt > newFile.txt

certains diront pour couper

cut -f1,2,5- temp.txt

qui produire la même sortie, et la coupe est grande pour la simplicité, mais ne gère pas les délimiteurs incohérents. Par exemple mélange de différents espaces. Cependant, dans ce cas, la coupe peut être ce que vous recherchez.

vous pourriez aussi accomplir ceci en perl, python, ruby,et beaucoup d'autres, mais voici le plus simple awk la solution.

6
répondu matchew 2011-06-23 18:19:12

Que penser de quelque chose de la forme:

cat SOURCEFILE | cut -f1-2,5- >> DESTFILE

Il imprime les deux premières colonnes, saute de la 3ème et 4ème, puis imprime à partir de 5 jusqu'à la fin.

6
répondu thomascirca 2011-06-23 18:23:19

pourquoi ne pas simplement définir les troisième et quatrième colonnes à une chaîne vide:

echo 1 2 3 4 5 6 7 8 9 10 |
awk -F" " '{ ="";  =""; print}'
1
répondu jim 2011-06-23 18:04:42

Oui, il est possible de définir les troisième et quatrième colonnes à une chaîne vide; mais, en outre, le champ devrait être réglé sur lui-même (=) pour faire awk en fait consommer le séparateur de champ d'entrée (delimètre) : sur toute la ligne actuelle }'

0
répondu progz 2013-03-18 12:59:01

Le dur, mais de façon générique (pour oublier un simple oneliner)

awk -v "Exclude=3:4:5" '
   # load exclusion
   BEGIN{
      Count=split(Exclude, aTmp, ":")
      for( i = 1; i <= Count; i++) aExc[ aTmp[ i]]=1
      }

   # treat each line, taking only wanted field
   {
    Result=""
    for( i = 1; i <= NF; i++) {
       # field to take ?
       if( ! aExc[ i]) {
         # first element or add a separator before
         if( Result != "") Result=Result OFS $i
          else Result=$i
         }
       }

    print Result
   }' YourFile
  • vous pouvez spécifier n'importe quel domaine que vous souhaitez exclure
    • remplissez le champ d'index en fait Exclure séparés par un : en première ligne
  • séparateur sont corrects en place une quantité
  • le code est "étendu" pour mieux comprendre
  • le résultat final n'est pas exactement comme input (sans le champ exclu) parce que le le séparateur de sortie est utilisé à la place du séparateur d'origine (ex 2 space ou un onglet est changé à 1 espace avec le comportement par défaut)
0
répondu NeronLeVelu 2015-08-06 08:31:18