Comment supprimer la dernière colonne dun fichier sous Linux

Je souhaite supprimer la dernière colonne dun fichier txt, alors que je ne sais pas quel est le numéro de colonne est. Comment pourrais-je faire cela?

Exemple:

Entrée:

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 

Commentaires

  • Il y a plusieurs façons de faire cela..veuillez ajouter un exemple et votre résultat attendu ..
  • @heemayl ok je lai fait
  • Merci..les colonnes sont-elles séparées par des tabulations ou séparées par des espaces?
  • @heemayl space is deliminator
  • cut sonne comme loutil pour le travail.

Réponse

Avec awk:

awk "NF{NF-=1};1" <in >out 

ou:

awk "NF{NF--};1" <in >out 

ou:

awk "NF{--NF};1" <in >out 

Bien que cela ressemble à du vaudou, cela fonctionne. Il y a trois parties dans chacune de ces commandes awk.

La première est NF, qui est une condition préalable pour 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 NF nest pas 0.

La deuxième partie (soit NF-=1 ou --NF) est juste en soustrayant un de la variable NF. Cela empêche le dernier champ dêtre imprimé, 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 nest pas magique, cest juste utilisé comme une expression qui signifie true. Si une expression awk prend la valeur true sans aucune action associée, awk laction par défaut est print $0 .

Commentaires

  • @JJoao: Ah, merci, jai oublié --. Une note, actuellement, vous avez besoin de ;1 pour être compatible POSIX.
  • Mon instinct initial serait dutiliser une boucle for, mais cest beaucoup plus concis et intelligent.
  • Il est ‘ de noter que si vous ‘ utilisez un séparateur autre que celui par défaut, vous ‘ ll faudra faire quelques changements. En supposant que , est votre délimiteur: awk -F',' 'BEGIN { OFS = FS }; NF { NF -= 1 }; 1' < in > out
  • Leffet de la décrémentation de NF est un comportement non défini par POSIX – vous obtiendrez sortie différente selon le awk que vous ‘ exécutez. Certains awks supprimeront le dernier champ comme vous le souhaitez, certains ne feront rien du tout et dautres pourraient signaler une erreur de syntaxe ou autre chose.

Réponse

Utilisation de grep avec PCRE:

$ grep -Po ".*(?=\s+[^\s]+$)" file.txt 1223 1234 1323 ... 2222 1233 1234 1233 ... 3444 0000 5553 3455 ... 2334 

Utilisation de GNU sed:

$ sed -r "s/(.*)\s+[^\s]+$/\1/" file.txt 1223 1234 1323 ... 2222 1233 1234 1233 ... 3444 0000 5553 3455 ... 2334 

Commentaires

  • @ramin Bien sûr. .Pouvez-vous la poser en tant que une nouvelle question (voici comment ce site fonctionne) 🙂
  • @ramin Vous en donne-t-il une restriction de temps ou un avertissement?
  • cela dit que cest hors de question!
  • @ramin Ok .. laissez-moi contacter un administrateur, il pourra peut-être vous aider. btw avez-vous vérifié un ancien QA concernant votre question? cest une possibilité que la question soit déjà posée et répondue ..
  • Ne ‘ t poser des questions super basiques comme  » comment puis-je renommer un nom de fichier sous Linux « . Utilisez Google.

Réponse

Utilisation de Perl:

perl -lane "$,=" ";pop(@F);print(@F)" in 

Utilisation de rev + cut:

rev in | cut -d " " -f 2- | rev 

Réponse

Utilisation de GNU sed:

sed -r "s/\s+\S+$//" input.txt 

Plus généralement, celui-ci fonctionne avec BSD sed sous OSX, ainsi quavec GNU sed:

sed "s/[[:space:]]\{1,\}[^[:space:]]\{1,\}$//" input.txt 

Answer

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 juste la première ligne de votre fichier dentrée, compter les délimiteurs ( n délimiteurs signifie que le nombre de champs est n+1) puis utilisez cut pour imprimer à partir de 1 st champ jusquau n ième champ (avant-dernier), par exemple avec une entrée délimitée par des tabulations:

n=$(head -n 1 infile | tr -dc \\t | tr \\t \\n | wc -l) cut -f1-$n infile > outfile 

ou par ex.avec un fichier csv :

n=$(head -n 1 infile | tr -dc , | tr , \\n | wc -l) cut -d, -f1-$n infile > outfile 

Je « lancerai quelques benchmarks plus tard si jai le temps mais avec une énorme contribution je pense que ceci La solution devrait être plus rapide que les autres solutions qui utilisent regex car celle-ci effectue un traitement minimal sur la première ligne pour obtenir le nombre de champs, puis utilise cut qui est optimisé pour ce travail.

Réponse

De manière portable, vous pouvez utiliser lun ou lautre de ces éléments:

sed "s/[[:space:]]*[^[:space:]]*$//" file awk "{sub(/[[:space:]]*[^[:space:]]*$/,"")}1" file 

Réponse

Utilisation de vim:

Ouvrez le fichier dans vim

vim <filename> 

Aller à la première ligne, juste au cas où le curseur serait placé ailleurs.

gg 

Créez une macro nommée « q » qq, qui va à larrière de la ligne courante $, puis revient au dernier espace F (F majuscule, suivi de SPACE littéral) puis supprimer de la position actuelle jusquà la fin de la ligne D allez à la ligne suivante j et arrêtez lenregistrement de la macro avec q.

qq$F Djq 

Nous pouvons maintenant répéter notre macro avec @q pour chaque ligne.
Nous pouvons également appuyer sur @@ pour répéter la dernière macro ou même plus facilement:

99@q 

pour répéter la macro 99 fois.
Remarque: Le nombre ne doit pas correspondre exactement aux lignes.

Réponse

Pour les personnes qui ont un problème similaire mais avec des séparateurs de champs différents, ceci awk conservera correctement le séparateur de champ:

$ cat file foo.bar.baz baz.bar.foo $ awk -F"." "sub(FS $NF,x)" file foo.bar baz.bar 

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *