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.
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 }'
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.
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.
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}'
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 }'
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
- remplissez le champ d'index en fait Exclure séparés par un
- 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)