Il file che hai mostrato ha tutti i dettagli su una riga:
name : farah age : 23 phone number : 0123 education : degree
Ho ipotizzato che sia possibile inserire un codice age :nel codice ecc. Nel comando, ma il testo che segue varierà e che i dettagli potrebbero non essere nell'ordine dato o essere contigui.
Puoi estrarre parti della linea con grepla -obandiera di. Questo stampa solo la parte abbinata, anziché l'intera linea.
Se si desidera includere le parti age :e phone number :, è possibile utilizzare il -eflag per specificare più corrispondenze oppure alternare.
$ grep -oe 'age : [^ ]*' -e 'phone number : [^ ]*' file
age : 23
phone number : 0123
L'espressione [^ ]*indica un numero qualsiasi di caratteri che non sono uno spazio, quindi corrisponde ai caratteri dopo age :fino allo spazio successivo.
Sostituisci filecon il nome del file che contiene i tuoi dettagli. È possibile scrivere il nuovo file reindirizzando l'output su un nuovo file con l' >operatore, in questo modo:
grep -oe 'age : [^ ]*' -e 'phone number : [^ ]*' file > outfile
Quando lo fai, non vedrai alcun output. Dovresti prima controllare l'output, quindi aggiungere il reindirizzamento.
Ecco l'esempio con l'alternanza. Usiamo la -Ebandiera per dire grepdi usare regex esteso. La sintassi è (pattern1|pattern2): questo corrisponde pattern1e / o pattern2. Se viene trovato uno dei due, verrà stampato (indipendentemente dal fatto che l'altro venga trovato o meno). Ora sto usando il +significato di almeno uno del carattere precedente, invece di *indicare zero o più del carattere precedente. In questo contesto, entrambi funzionano ugualmente bene.
$ grep -Eo '(age : [^ ]+|phone number : [^ ]+)' file
age : 23
phone number : 0123
Se si desidera omettere le parti age :e phone number:, è possibile utilizzare la -Pbandiera per chiedere grepdi utilizzare espressioni regolari compatibili con Perl. Questo supporta l'alternanza e anche un modo per abbinare il testo dopo un determinato modello:
$ grep -Po '(age : \K[^ ]+|phone number : \K[^ ]+)' file
23
0123
Se si desidera formattare il testo in modo diverso, è possibile utilizzare sed, ad esempio:
$ sed -r 's/.*(age) : ([^ ]*).*(phone number) : ([^ ]*).*/\1:\2 | \3:\4/' file
age:23 | phone number:0123
Questo dipende dal fatto di agevenire prima phone number, quindi aggiusta di conseguenza se non è così. Se non puoi fare affidamento sull'ordine, puoi utilizzare questo comando molto contorto:
$ sed -r 's/(.*)(phone number : [^ ]+)(.*) .*/\2 \1\4/; s/(phone number) : ([^ ]+) .*(age) : ([^ ]+).*/\1: \2 | \3: \4/' file
phone number: 0123 | age: 23
Questo riorganizza la linea in modo che la phone number :sezione venga prima su ogni riga, quindi effettua una seconda sostituzione per selezionare i dettagli desiderati. Devo la tecnica qui usata a questa risposta di Muru .
Note su sedcomandi non coperti da spiegazioni precedenti
-rusa regex esteso per comandi più leggibili (GNU sedcapisce -Econ lo stesso significato)
s/old/new/sostituire oldconnew
(pattern)salva patternin riferimento in seguito, con \1o \2etc (corrispondente all'ordine da sinistra a destra in cui si verificano i gruppi di acquisizione - nota che sedconterrà solo fino a 7 di questi!).
.qualsiasi carattere, quindi .*rappresenta un numero qualsiasi di qualsiasi carattere.
; separa i comandi, come nella shell.