Je souhaite supprimer la dernière colonne d'un fichier txt, alors que je ne connais pas le numéro de colonne. Comment pourrais-je faire ça?
Exemple:
Contribution:
1223 1234 1323 ... 2222 123
1233 1234 1233 ... 3444 125
0000 5553 3455 ... 2334 222
Et je veux que ma sortie soit:
1223 1234 1323 ... 2222
1233 1234 1233 ... 3444
0000 5553 3455 ... 2334
text-processing
sed
awk
perl
zara
la source
la source
Réponses:
Avec
awk
:ou:
ou:
Bien que cela ressemble à du vaudou, cela fonctionne. Chacune de ces commandes awk comprend trois parties.
Le premier est
NF
, qui est une condition préalable à la deuxième partie.NF
est une variable contenant le nombre de champs dans une ligne. Dans AWK, les choses sont vraies si elles ne sont pas 0 ou une chaîne vide""
. Par conséquent, la deuxième partie (oùNF
est décrémentée) ne se produit que si elleNF
n'est pas 0.La deuxième partie (soit
NF-=1
NF--
ou--NF
) en soustrait simplement une de laNF
variable. Cela empêche l'impression du dernier champ, car lorsque vous modifiez un champ (en supprimant le dernier champ dans ce cas),awk
reconstruisez$0
, concaténez tous les champs séparés par un espace par défaut.$0
ne contenait plus le dernier champ.La dernière partie est
1
. Ce n'est pas magique, c'est juste utilisé comme une expression qui signifietrue
. Si uneawk
expression est évaluée à true sans aucune action associée, l'actionawk
par défaut estprint $0
.la source
--
. Une note, actuellement, vous avez besoin;1
pour la conformité POSIX.,
votre délimiteur:awk -F',' 'BEGIN { OFS = FS }; NF { NF -= 1 }; 1' < in > out
Utilisation
grep
avec PCRE:Utilisation de GNU
sed
:la source
Utilisation de Perl:
Utiliser
rev
+cut
:la source
Utilisation de GNU sed:
Plus généralement, celui-ci fonctionne avec le BSD sed dans OSX, ainsi que GNU sed:
la source
Si le délimiteur est toujours un seul caractère (donc deux délimiteurs consécutifs ou plus désignent des champs vides), vous pouvez
head
simplement la première ligne de votre fichier d'entrée, compter les délimiteurs (n
délimiteurs signifie que le nombre de champs estn+1
) puis utilisercut
pour imprimer à partir du1
champ st jusqu'aun
champ e (avant-dernier), par exemple avec une entrée délimitée par des tabulations:ou par exemple avec un fichier csv :
J'exécuterai quelques benchmarks plus tard si j'ai le temps, mais avec une énorme contribution, je pense que cette solution devrait être plus rapide que d'autres solutions qui utilisent l'expression régulière car celle-ci effectue un traitement minimal sur la première ligne pour obtenir le non. des champs, puis utilise
cut
ce qui est optimisé pour ce travail.la source
Vous pouvez utiliser l'un ou l'autre de ces éléments:
la source
Utilisation de vim:
Ouvrir un fichier dans vim
Allez à la première ligne, juste au cas où le curseur serait placé ailleurs.
Créez une macro nommée "q"
qq
, qui va à l'arrière de la ligne actuelle$
, puis retourne au dernier espaceF
(F majuscule, suivi par ESPACE littéral) puis supprimez de la position actuelle jusqu'à la fin de la ligne,D
descendez à la ligne suivantej
et arrêter l'enregistrement de macro avecq
.Maintenant, nous pouvons répéter notre macro avec
@q
pour chaque ligne.Nous pouvons également appuyer sur
@@
pour répéter la dernière macro ou encore plus facilement:pour répéter la macro 99 fois.
Remarque: le nombre ne doit pas correspondre exactement aux lignes.
la source
Pour les personnes qui ont un problème similaire mais avec des séparateurs de champs différents, cette
awk
méthode préservera correctement le séparateur de champs:la source