2013-02-03 8 views
14

Ho un file di testo che ha il seguente formato:grep: corrisponde a tutti i caratteri fino a (escluso) primo spazio vuoto

characters(that I want to keep) (space) characters(that I want to remove) 

Così, per esempio:

foo garbagetext 
hello moregarbage 
keepthis removethis 
(etc.) 

Così ho cercato utilizzare il comando grep in Linux per mantenere solo i caratteri di ogni riga e senza includere il primo spazio vuoto. Ho provato i numerosi tentativi, quali:

grep '*[[:space:]]' text1.txt > text2.txt 
grep '*[^\s]' text1.txt > text2.txt 
grep '/^[^[[:space:]]]+/' text1.txt > text2.txt 

cercando di mettere insieme da diversi esempi, ma non ho avuto fortuna. Tutti producono un file vuoto text2.txt. Sono nuovo in questo. Che cosa sto facendo di sbagliato?

* EDIT:

Le parti Voglio continuare a includere le lettere maiuscole. Quindi voglio mantenere qualsiasi/tutti i caratteri fino a e non includendo lo spazio (rimuovendo tutto dallo spazio vuoto in poi) in ogni riga.

** EDIT:

Il testo spazzatura (che voglio rimuovere) può contenere qualsiasi cosa, inclusi gli spazi, caratteri speciali, ecc Così, per esempio:

AA rough, cindery lava [n -S] 

Dopo aver eseguito grep -o '[^ ]*' text1.txt > text2.txt, il riga sopra diventa:

AA 
rough, 
cindery 
lava 
[n 
-S] 

in text2.txt. (Tutto quello che voglio mantenere è AA)


SOLUZIONE (fornito da Rohit Jain con un ulteriore ingresso per beny23):

grep -o '^[^ ]*' text1.txt > text2.txt 

risposta

20

Si sta mettendo quantifier * nel posto sbagliato.

Prova invece questa: -

grep '^[^\s]*' text1.txt > text2.txt 

o, meglio ancora: -

grep '^\S*' text1.txt > text2.txt 

\S significa partita non-spazi carattere. E l'ancoraggio ^ viene utilizzato per abbinare all'inizio della linea.

+1

Include la maiuscola? Ho eseguito entrambi e produce solo lo stesso file. Vorrei rimuovere tutto dallo spazio in poi (mantenendo "foo" "ciao" e "keepthis" nell'esempio che ho dato). –

+0

@lord_sneed .. Puoi provare di nuovo. Ho aggiunto l'ancora '^', che si abbina solo all'inizio della riga. –

+0

Questo ancora solo riduplica il file. Ho corso di nuovo entrambi. : S –

0

Io uso egrep molto per aiutare a "colorare" le righe di registro, quindi sono sempre alla ricerca di una nuova svolta in regex. Per me, quanto sopra funziona meglio con l'aggiunta di un \ W come questo:

$ egrep --color '^\S*\W|bag' /tmp/barf -o 
foo 
bag 
hello 
bag 
keepthis 
(etc.) 

Il problema è che i miei file di log sono quasi sempre data e ora, così ho aggiunto una riga al file di esempio:

2013-06-11 date stamped line 

e quindi non funziona così bene. Così sono ritornato al mio regex precedente:

egrep --color '^\w*\b|bag' /tmp/barf 

ma le linee non-data-timbrato rivelato problemi con che. È difficile vederlo senza colorazione ...

11

Mi rendo conto che da tempo si è già risposto con la soluzione grep, ma per le generazioni future vorrei notare che ci sono almeno altre due soluzioni per questa particolare situazione , entrambi sono più efficienti di grep.

Poiché non si sta eseguendo alcuna corrispondenza di modelli di testo complessi, basta prendere la prima colonna delimitata da uno spazio, è possibile utilizzare alcune delle utilità basate su colonne, come awk o cut.

Utilizzando awk

$ awk '{print $1}' text1.txt > text2.txt 

Usare cut

$ cut -f1 -d' ' text1.txt > text2.txt 

benchmark su un file ~ 1.1MB

$ time grep -o '^[^ ]*' text1.txt > text2.txt 

real 0m0.064s 
user 0m0.062s 
sys  0m0.001s 
$ time awk '{print $1}' text1.txt > text2.txt 

real 0m0.021s 
user 0m0.017s 
sys  0m0.004s 
$ time cut -f1 -d' ' text1.txt > text2.txt 

real 0m0.007s 
user 0m0.004s 
sys  0m0.003s 

awk è circa 3 volte più veloce di grep e cut è circa 3 volte più veloce di quello. Ancora una volta, non c'è molta differenza per questo file di piccole dimensioni per una sola esecuzione, ma se stai scrivendo uno script, ad es. Per riutilizzarlo, o farlo spesso su file di grandi dimensioni, potresti apprezzare la maggiore efficienza.

+0

L'approccio "taglia" è il mio preferito –

Problemi correlati