rimuovendo il primo e l'ultimo carattere di ogni riga dalla riga di comando


8

Sto cercando di rimuovere il primo e l'ultimo carattere di ogni riga in un file di testo e salvare la versione troncata risultante in un nuovo file. Qualcuno ha un'idea di come farlo in modo efficiente utilizzando awko altri programmi / comandi Linux specificamente per file di grandi dimensioni?

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)

Output.txt previsto

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

Risposte:


14

Un altro modo solo per il diavolo:

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

(Nota: con GNU cut, funziona solo con caratteri costituiti da un solo byte (come nell'esempio)).


Bello! Questo è significativamente più veloce delle soluzioni sed e awk proposte finora.
Gilles 'SO- smetti di essere malvagio' il

Ho proposto questa risposta per le persone che hanno paura della sintassi sed / awk / regex, ma non avrei mai immaginato che sia più veloce, specialmente per file di grandi dimensioni, con tre pipe e passando l'intero contenuto attraverso ognuna. Avrei pensato che sed o awk leggere una riga alla volta sarebbero stati più efficienti per file di grandi dimensioni.
Drake Clarris,

3
Immagino che questo ti porterà oltre 40 anni di ottimizzazione di molte di queste utility * nix!
Drake Clarris,

@Gilles, è più veloce GNU sed in localizzazioni utf8 per alcune forme di input, e dipende se stai prendendo in considerazione l'ora del wall clock o la CPU. ssedoppure il toolchest Heirloom sedpuò ottenere prestazioni migliori.
Stéphane Chazelas,

@Gilles Non esiste alcuna voce MAN per il giro in Solaris 5.10. Ho finito per usaresed
ayrton_senna il

10

Come da tua domanda cancella l'ultima e la prima parola dal file di input come di seguito:

sed 's/.$//; s/^.//' inputfile

Sarebbe bello se si potesse punto di riferimento questi contro l'altra soluzione, s/.\(.*\).$/\1/. Potrebbe essere più veloce a causa del mancato utilizzo di backreferences e la domanda menzionava "file di grandi dimensioni".
1313

4
@ l0b0 Ho provato con time yes | head -n 10000000 | COMMAND >/dev/null. Ottengo rev input | cut -c2- | rev | cut -c2-→ 0.14s, sed 's,.\(.*\).$,\1,'→ 3.38s; awk '{print substr($0,2,length()-2);}'→ 3.50s; sed 's/.$//; s/^.//'→ 5.09s.
Gilles 'SO- smetti di essere malvagio' il

@Gilles +1 Dovrebbe essere una risposta.
10

2
@Gilles, sono linee molto brevi. Trovo che per tratte di 30 caratteri, la soluzione di @ RahulPatil è 3 volte più veloce con GNU sed rispetto a quella di @ juampa. Anche. sed 's/.\(.*\)./\1/'sembra essere più veloce di sed 's/^.\(.*\).$/\1/'(GNU sed di nuovo). Inoltre, le prestazioni dipendono seddalle impostazioni locali (interpretazione di cosa sia un personaggio) e dall'implementazione (a tale proposito, sed dal toolchest cimelio è considerevolmente più veloce di GNU sed).
Stéphane Chazelas,

5

Ci sono molte possibilità, come sempre

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

Spiegazione

  • , - il delimitatore sed, può essere anche qualsiasi altro personaggio, dato che è sfuggito dove mai necessario.
  • . Abbina un singolo personaggio
  • \(.*\) - Raggruppa la parte rimanente e questa viene memorizzata per essere recuperata ulteriormente.
  • . Abbina di nuovo un singolo personaggio
  • $ - Fine linea
  • \1 - genera il testo corrispondente al gruppo sopra
  • g sostituire a livello globale sulla linea.

2
Perché g? ci sarà solo una corrispondenza per riga.
njsg

Nota che non rimuoverà nulla dalle righe che hanno meno di 2 caratteri.
Stéphane Chazelas,

3

Puoi anche farlo con awkse preferisci

awk '{print substr($0,2,length()-2);}' input.txt > output.txt

2
tr -d '()[]{}"' < your_file

Anche questo dovrebbe funzionare. Ben "traduce" a zero ogni carattere (elimina).

Il rovescio della medaglia è che li eliminerà se non sono anche il primo / ultimo carattere. Mancherà anche qualsiasi personaggio finale che non elenchi in ()[....

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.