Come posso eliminare la quinta parola di ogni riga di un file?


13

Voglio eliminare la quinta parola di ogni riga in un file.

Il contenuto corrente del file:

File is not updated or and will be removed  
System will shut down f within 10 seconds  
Please save your work 55 or copy to other location  
Kindly cooperate with us D  

Uscita prevista:

File is not updated and will be removed  
System will shut down within 10 seconds  
Please save your work or copy to other location  
Kindly cooperate with us

Risposte:


31

Che ne dici di cut:

$ cut -d' ' -f1-4,6- file.txt 
File is not updated and will be removed  
System will shut down within 10 seconds  
Please save your work or copy to other location  
Kindly cooperate with us
  • -d' ' imposta il delimitatore come spazio

  • -f1-4,6- seleziona dal primo al quarto campo (parola), lasciando il quinto e quindi continua a stampare dal 6 ° al resto.


11

Una soluzione con cut:

cut -d ' ' -f1-4 -f6- FILE

Il multiplo -fnon è supportato nel mio cut(GNU) almeno ..
— heemayl

Supportato nel taglio BSD ma mi piace la tua risposta meglio della mia.
— f0,

1
Se si tratta di GNU taglio, si ottiene la --complementbandiera per semplificare le cose: cut --complement -d ' ' -f5. Ricorda di reindirizzare l'output su un nuovo file, quindi mvsull'originale.
— Toby Speight,

6

awk: rimuove il 5 ° campo

awk '{for (i=5; i<NF; i++) $i = $(i+1); NF--};1' file

Se si desidera salvare il file sul posto: /programming//q/16529716/7552

Potresti semplicemente cancellare il contenuto del 5 ° campo, ma ciò lascia 2 separatori di campi di output consecutivi:

awk '{$5 = ""};1' file

l'avvertenza qui è che la modifica del valore di qualsiasi campo in awk ha l'effetto collaterale di riscrivere l'intero "$ 0" con solo 1 separatore tra ciascun campo. dovrebbe essere preso in considerazione se si desidera mantenere qualsiasi allineamento (a meno che gnu awk non abbia un'opzione per evitarlo? awk / nawk regolare calcolerà $ 0)
— Olivier Dulac

In entrambi i casi, riformattare la linea con un singolo separatore. Se in un separatore sono presenti 2 spazio o spazio + scheda, il risultato è un singolo spazio in atto. Questo è hoppefully OK per la maggior parte del testo.
— NeronLeVelu,

4

Con POSIX sed:

sed -e 's/[^[:alnum:]_][[:alnum:]_][[:alnum:]_]*//4' <file

perché limitare la classe a: alnum: _ e non qualcos'altro allora :blank:o :space:?
— NeronLeVelu,

@NeronLeVelu: dipende da come definisci ciò che crea una parola.
— cuonglm

@mikeserv; Bella presa! Ho aggiornato la mia risposta.
— cuonglm,

A cosa \(serve il gruppo di acquisizione \)?
— Mikeserv,

@mikeserv: il mio errore di battitura, ho appena provato alcuni modi per conservare il delimitatore.
— cuonglm,

2

glenn ha offerto una soluzione equivalente

awk '{$ 5 = ""; stampare}' di file

Come lui e altri hanno sottolineato, questo

  1. striscia gli spazi bianchi iniziali e finali di ogni riga,
  2. comprime ogni stringa di spazi bianchi (spazi e / o tabulazioni) in un singolo spazio e
  3. lascia due spazi tra la quarta e le sei parole.

Un trucco per risolvere il terzo problema è

awk '{$ 5 = ""; print} ' file | sed 's / / /'

Ciò lascerà comunque uno o più spazi aggiunti alla fine di qualsiasi riga in cui sono state inserite cinque o meno parole. Se riesci a identificare una parola che non verrà mai visualizzata nell'input,

awk '{$ 5 = "unicorno"; print} ' file | sed 's / * unicorn //'

gestirà anche quello (ma lascia ancora i problemi 1 e 2).


2
 sed 's/^\(\([[:blank:]]*[^[:blank:]]\{1,\}\)\{4\}\)[[:blank:]]*[^[:blank:]]*/\1/' YourFile > Output.txt
  • posix sed basato sul separatore spazio / tabulazione (meta class [: blank:]])
  • mantenere lo spazio seguente dopo la quinta parola ma rimuovendo quella precedente

Un modello più robusto (sed prende il modello più lungo possibile e il modello con *potrebbe mancare la separazione o la parola nella prima versione) ma una versione un po 'più lunga

sed 's/^\([[:blank:]]*\([^[:blank:]]\{1,\}[[:blank:]]\{1,\}\)\{4\}\[^[:blank:]]\{1,\}/\1/' YourFile > Output.txt

1
sed 's/[^[:blank:]]*//5'
— Mikeserv,

@mikeserv, questo manterrà entrambi i separatori circostanti, sed 's/[[:blank:]*[^[:blank:]]*//5'è meglio. Ottimo punto Sospettavo che sed prendesse ogni singolo carattere come entità, ma prende il più grande schema non
— frazionato

sed 's/[[:blank:]][^[:blank:]]*//4'rimuoverà completamente il 5 ° campo.
— Mikeserv,

@mikeserv Supponendo che non ci sia spazio iniziale sulla linea (come nel campione)
— NeronLeVelu

In questo caso, sì, penso che tu abbia ragione. Di solito una cosa del genere sarebbe un campo nullo e il comportamento sarebbe corretto. In questo caso si dovrebbe fare come ha fatto @cuonglm e garantire si fa riferimento a una parola ogni volta come sed 's/[[:blank:]][^[:blank:]][^[:blank:]]*//4', o, w / GNU / BSD / Toybox seds: sed -E 's/[[:blank:]][^[:blank:]]+//4'.
— Mikeserv,

1

Perl.

perl -ne 'print $_ =~ /^(\w+ +\w+ +\w+ +\w+ +)\w+ (.*)/,"\n"' file

1

Un'altra possibilità, supponendo che GNU abbia tagliato:

cut -d' ' -f5 --complement file.txt

-1

Utilizzo di Perl> 5.10 (e uscita corretta di tutte le righe: 0)): -

perl -nE '/^((\w+ +){4})\w+ *(.*)/; say $1.$3' file
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.