2013-01-04 11 views
6

Ho un insieme di dati che assomiglia a questocercare più condizionata stringa con awk

col1 col2 col3 col4 
ABC1 DEF1 GHI1 cond1 
ABC2 DEF2 GHI2 cond1-cond2 
ABC3 DEF3 GHI3 cond2/cond1 
ABC4 DEF4 GHI4 cond2 cond1 
ABC5 DEF5 GHI5 cond4/cond1 
ABC6 DEF6 GHI6 cond1 
ABC7 DEF7 GHI7 mcond1 
ABC8 DEF8 GHI8 cond2 
ABC9 DEF9 GHI9 cond1 at 50 
ABCa DEFa GHIa con cond1 
ABCb DEFb GHIb no. cond1 
ABCc DEFc GHIc cond1 something 
ABCc DEFc GHIc Mcond1 

Sto cercando di scrivere un paio di comandi per separare i dati secondo il "col4" per ottenere:

  1. Un file che contiene la stringa "cond1" con QUALSIASI prima o dopo ESCLUSO per le lettere "M" e "m". Attualmente sto usando questo comando (che non esclude M ed m, ovviamente) per questo:

    awk 'BEGIN{IGNORECASE=1} $4 ~ /.cond1/ || $4 ~ /cond1./ ' /filepath.tab 
    

    prega, inoltre, non che il 4 °, 9 ° e il 11 ° righe di dati contengono spazi tra "cond1" e altri stringhe, voglio questo INCLUSO nel file. (Non il "" nel comando includere spazi?)

  2. ho scritto un comando per ottenere un file che contiene 'cond1' solo nel 'col4'

    awk 'BEGIN{IGNORECASE=1} $4 ~ /^cond1$/ ' /filepath.tab 
    

    si sta lavorando bene con la maggior parte dei dati, anche se io sono sempre questi 2 errori nei risultati:

    ABC9 DEF9 GHI9 cond1 at 50 
    ABCc DEFc GHIc cond1 something 
    

qualcuno può per favore mi aiuti con questi 2 comandi? Grazie.

Sto cercando una potenza di 3 file che non contiene duplicati, ecco un esempio: File1 (contenente tutte le combinazioni con cond1):

col1 col2 col3 col4 
ABC2 DEF2 GHI2 cond1-cond2 
ABC3 DEF3 GHI3 cond2/cond1 
ABC4 DEF4 GHI4 cond2 cond1 
ABC5 DEF5 GHI5 cond4/cond1 
ABC9 DEF9 GHI9 cond1 at 50 
ABCa DEFa GHIa con cond1 
ABCb DEFb GHIb no. cond1 
ABCc DEFc GHIc cond1 something 

File2 (contenente COND1 solo):

col1 col2 col3 col4 
ABC1 DEF1 GHI1 cond1 
ABC6 DEF6 GHI6 cond1 

File3 (contiene tutto ciò che non è stato incluso nel file1 e file2):

col1 col2 col3 col4 
ABC7 DEF7 GHI7 mcond1 
ABC8 DEF8 GHI8 cond2 
ABCc DEFc GHIc Mcond1 

Si noti che le file totali dei 3 file sono uguali a quelle del file originale Mi dispiace se questo sembra piuttosto complicato, ma questo è il caso che effettivamente ho.

+0

Qual è il tuo desiderato produzione! –

+0

Qual è il separatore tra le colonne? è tab? se il suo spazio 11a riga 4a colonna non conterrà 'cond1'. È la quinta colonna lì –

+0

Sì, si tratta di un file separato da tabulazioni e, a volte, c'è un unico spazio tra le parole. (e sono sicuro che non si tratta di colonne diverse, perché questo era un file di grandi dimensioni e ho usato il taglio per togliere solo queste 4 colonne) – Error404

risposta

2

Il problema è che la colonna 4 ha spazi e il file non è formattato come previsto provare awk -F'\t' {print $4} file e notare che non è probabilmente quello che ci si aspetta.

Prima girare il file in formato CSV con sed

$ sed 's/\s\+/,/;s/\s\+/,/;s/\s\+/,/;' file 
col1,col2,col3,col4 
ABC1,DEF1,GHI1,cond1 
ABC2,DEF2,GHI2,cond1-cond2 
ABC3,DEF3,GHI3,cond2/cond1 
ABC4,DEF4,GHI4,cond2 cond1 
ABC5,DEF5,GHI5,cond4/cond1 
ABC6,DEF6,GHI6,cond1 
ABC7,DEF7,GHI7,mcond1 
ABC8,DEF8,GHI8,cond2 
ABC9,DEF9,GHI9,cond1 at 50 
ABCa,DEFa,GHIa,con cond1 
ABCb,DEFb,GHIb,no. cond1 
ABCc,DEFc,GHIc,cond1 something 
ABCc,DEFc,GHIc,Mcond1 

Questo converte solo i primi 3 gruppi spazi bianchi per le virgole che lasciano col4 come si desidera. Per memorizzare la modifica nel file utilizzare l'opzione -i:

sed -i 's/\s\+/,/;s/\s\+/,/;s/\s\+/,/;' file 

Ora il separatore di campo , può essere utilizzato.

awk 'BEGIN{FS=",";OFS="\t"} NR==1{print $1,$2,$3,$4} $4~/cond1./|| $4~/[^mM]cond1/{print $1,$2,$3,$4}' file 
col1 col2 col3 col4 
ABC2 DEF2 GHI2 cond1-cond2 
ABC3 DEF3 GHI3 cond2/cond1 
ABC4 DEF4 GHI4 cond2 cond1 
ABC5 DEF5 GHI5 cond4/cond1 
ABC9 DEF9 GHI9 cond1 at 50 
ABCa DEFa GHIa con cond1 
ABCb DEFb GHIb no. cond1 
ABCc DEFc GHIc cond1 something 

$ awk 'BEGIN{FS=",";OFS="\t"} NR==1{print $1,$2,$3,$4} $4~/^cond1$/{print $1,$2,$3,$4}' file 
col1 col2 col3 col4 
ABC1 DEF1 GHI1 cond1 
ABC6 DEF6 GHI6 cond1 

$ awk 'BEGIN{FS=",";OFS="\t"} $4!~/cond1/ || $4~/[Mm]cond1/{print $1,$2,$3,$4}' file 
col1 col2 col3 col4 
ABC7 DEF7 GHI7 mcond1 
ABC8 DEF8 GHI8 cond2 
ABCc DEFc GHIc Mcond1 

Proprio redirect per salvare le NewFiles awk '{...}' > file1.

+0

Ciao, grazie per il tuo comando. per il primo comando (dopo averlo trasformato in un file separato da virgola), anche gli spazi tra le parole diventano virgole. quindi ho perso i campi "cond1 a 50", "cond1 something", "cond2 cond1", "con cond1" e "no cond1". – Error404

+0

@ Error404 no il comando 'sed' è costruito in modo da sostituire solo i primi 3 gruppi di spazi bianchi con virgole, ho aggiornato la mia risposta per spiegarlo. –

+0

sì amico, grazie per la tua risposta ... ora che capisco il comando, so come catturare un pesce e mangerò ogni giorno :) – Error404

1

Poiché i campi sono separati da tabulazione, utilizzare FS="\t" nel blocco BEGIN. Anche le tue condizioni non sono corrette. Quindi l'ho cambiato.

awk 'BEGIN{IGNORECASE=1; FS="\t"; } $4 ~ /cond1/ && $4 !~ /mcond1|cond1m/' data 
+0

Grazie per il comando. In realtà funziona bene, ma voglio aggiungere qualcosa a questo comando. se avessi questo in col4 "mcond1 cond1" quindi se mcond1 e cond1 ci sono allo stesso tempo, voglio che sia incluso, se mcond1 fosse da solo o con qualcos'altro, quindi NO. come dico questo? – Error404

+0

Questo supera, include le linee 1 e 6, più nessuna intestazione. –

1

È possibile eseguire l'attività con un singolo passaggio. Esegui come:

awk -f script.awk file 

Contenuto del script.awk:

BEGIN { 
    FS="\t" 
} 

NR==1 { 
    r=$0 
    next 
} 

{ 
    i = ($4 == "cond1" ? 2 : ($4 ~ /cond1/ && $4 !~ /[Mm]cond1/ ? 1 : 3)) 
    print (!a[i]++ ? r ORS : "") $0 > "file" i ".txt" 
} 

Risultati di grep . file[1-3].txt:

file1.txt:col1 col2 col3 col4 
file1.txt:ABC2 DEF2 GHI2 cond1-cond2 
file1.txt:ABC3 DEF3 GHI3 cond2/cond1 
file1.txt:ABC4 DEF4 GHI4 cond2 cond1 
file1.txt:ABC5 DEF5 GHI5 cond4/cond1 
file1.txt:ABC9 DEF9 GHI9 cond1 at 50 
file1.txt:ABCa DEFa GHIa con cond1 
file1.txt:ABCb DEFb GHIb no. cond1 
file1.txt:ABCc DEFc GHIc cond1 something 
file2.txt:col1 col2 col3 col4 
file2.txt:ABC1 DEF1 GHI1 cond1 
file2.txt:ABC6 DEF6 GHI6 cond1 
file3.txt:col1 col2 col3 col4 
file3.txt:ABC7 DEF7 GHI7 mcond1 
file3.txt:ABC8 DEF8 GHI8 cond2 
file3.txt:ABCc DEFc GHIc Mcond1 

In alternativa, ecco l'one-liner:

awk -F "\t" 'NR==1 { r=$0; next } { i = ($4 == "cond1" ? 2 : ($4 ~ /cond1/ && $4 !~ /[Mm]cond1/ ? 1 : 3)); print (!a[i]++ ? r ORS : "") $0 > "file" i ".txt" }' file 
Problemi correlati