supprimer le premier et le dernier caractère de chaque ligne de la ligne de commande

8

J'essaie de supprimer les premier et dernier caractères de chaque ligne dans un fichier texte et d'enregistrer la version tronquée résultante dans un nouveau fichier. Quelqu'un at-il une idée sur la façon de le faire efficacement en utilisant awkou d'autres programmes / commandes Linux spécifiquement pour les gros fichiers?

input.txt

(s,2,4,5,6)
"s,1,5,5,2"
{z,0,4,5,3}
[y,2,4,5,5]
(y,4,4,5,7)
(r,20,4,5,7)
(e,9,4,5,2)

Sortie attendue.txt

s,2,4,5,6
s,1,5,5,2
z,0,4,5,3
y,2,4,5,5
y,4,4,5,79
r,20,4,5,7
e,9,4,5,2
pacodelumberg
la source

Réponses:

14

Une autre façon juste pour le plaisir:

rev input | cut -c2- | rev | cut -c2-

(Remarque: avec GNU cut, cela ne fonctionne que pour les caractères composés d'un seul octet (comme dans votre exemple)).

Drake Clarris
la source
Agréable! C'est nettement plus rapide que les solutions sed et awk proposées jusqu'à présent.
Gilles 'SO- arrête d'être méchant'
J'ai proposé cette réponse aux personnes qui ont peur de la syntaxe sed / awk / regex, mais je n'aurais pas imaginé que c'est plus rapide, en particulier pour les gros fichiers, avec trois canaux et en passant tout le contenu à travers chacun. Aurait pensé que sed ou awk lire une ligne à la fois serait plus efficace pour les gros fichiers.
Drake Clarris
3
Je suppose que c'est ce que plus de 40 ans d'optimisation de bon nombre de ces utilitaires * nix vous procureront!
Drake Clarris
@Gilles, il est plus rapide de GNU sed dans les locales utf8 pour certaines formes d'entrée, et cela dépend si vous envisagez l'heure de l'horloge murale ou le temps CPU. ssedou le Heirloom toolchest sedpeut obtenir de meilleures performances.
Stéphane Chazelas
@Gilles Theres aucune entrée MAN pour rev dans Solaris 5.10. J'ai fini par utilisersed
ayrton_senna
10

Selon votre question, supprimez le dernier et le premier mot du fichier d'entrée comme ci-dessous:

sed 's/.$//; s/^.//' inputfile
Rahul Patil
la source
Ce serait cool si vous pouviez référence ceux - ci contre l'autre solution, s/.\(.*\).$/\1/. Cela pourrait être plus rapide du fait de ne pas utiliser de références arrières, et la question mentionnait des "fichiers volumineux".
l0b0
4
@ l0b0 J'ai testé avec time yes | head -n 10000000 | COMMAND >/dev/null. Je reçois rev input | cut -c2- | rev | cut -c2-→ 0.14s, sed 's,.\(.*\).$,\1,'→ 3.38s; awk '{print substr($0,2,length()-2);}'→ 3,50 s; sed 's/.$//; s/^.//'→ 5,09 s.
Gilles 'SO- arrête d'être méchant'
@Gilles +1 Cela devrait être une réponse.
l0b0
2
@Gilles, ce sont des lignes très courtes. Je trouve que pour les lignes larges de 30 caractères, la solution de @ RahulPatil est 3 fois plus rapide avec GNU sed que celle de @ juampa. Aussi. sed 's/.\(.*\)./\1/'semble être plus rapide que sed 's/^.\(.*\).$/\1/'(GNU sed à nouveau). De plus, les performances dépendent des paramètres régionaux (interprétation de ce qu'est un personnage) et de l' sedimplémentation (à cet égard, sed du heirloom toolchest est considérablement plus rapide que GNU sed).
Stéphane Chazelas
5

Il existe de nombreuses possibilités, comme toujours

sed 's,.\(.*\).$,\1,g' your_file

Explication

  • , - le délimiteur sed, peut également être tout autre caractère, étant donné qu'il est échappé là où il le faut.
  • . Correspond à un seul caractère
  • \(.*\) - Regroupez la partie restante et celle-ci est stockée pour être récupérée ultérieurement.
  • . Faites correspondre à nouveau un seul caractère
  • $ - Fin de ligne
  • \1 - afficher le texte correspondant au groupe ci-dessus
  • g remplacer globalement sur la ligne.
jpmuc
la source
2
Pourquoi g? il n'y aura qu'un seul match par ligne.
njsg
Notez qu'il ne supprimera rien des lignes de moins de 2 caractères.
Stéphane Chazelas
3

Vous pouvez également le faire avec awksi vous préférez

awk '{print substr($0,2,length()-2);}' input.txt > output.txt
StrongBad
la source
2
tr -d '()[]{}"' < your_file

Cela devrait également fonctionner. Il "traduit" bien chacun des caractères en rien (supprimer).

L'inconvénient est qu'il les supprimera s'ils ne sont pas également le premier / dernier caractère. Il vous manquera également tous les caractères de fin que vous n’indiquez pas dans le ()[....

Mark Nichols
la source