Seleziona le righe in un file in base a valori specifici nel secondo file


0

Ho due file:

Uno è "total.txt". Ha due colonne: la prima colonna è numeri naturali (indicatore) che vanno da 1 a 20, la seconda colonna contiene numeri casuali.

1 321
1 423
1 2342
1 7542
2 789
2 809
2 5332
2 6762
2 8976
3 42
3 545
... ...
20 432
20 758

L'altro è "index.txt". Ha quattro colonne: (1.indicator, 2: low value, 3: high value, 4: Region name)

1 400 5000 R1
2 600 800 R2
2 4000 8000 R3
11 300 4000 R4

Voglio produrre le righe del file "total.txt" con le corrispondenze della prima colonna con la prima colonna del file "index.txt". E allo stesso tempo, la seconda colonna dei risultati di output deve essere più grande di (>) la seconda colonna di "index.txt" e più piccola di (<) la terza colonna di "index.txt". E anche il nome della regione dovrebbe essere allegato.

Il risultato atteso è il seguente:

1 423 R1
1 2342 R1
2 809 R2
2 5332 R3
2 6762 R3
11 ... R4
11 ... R4

Ho provato questo:

awk 'FNR == NR { low[$1]=$2; high[$1]=$3; reg[$1]=$4; next} 
     $2 >= low[$1] && $2 <= high[$1] {print $0,reg[$1]}' index.txt total.txt > result.txt

Il risultato viene fuori come segue (con la regione R2 mancante)

1 423 R1
1 2342 R1
2 5332 R3
2 6762 R3
11 ... R4
11 ... R4

Potete aiutarmi a spiegare questo e dirmi come gestirlo? Grazie!

In realtà, se i risultati possono essere emessi in base a regioni diverse è meglio, significa che in questo esempio è meglio produrre 4 file di testo relativi a regioni diverse (R1.txt, R2.txt, R3.txt e R4.txt). Grazie!


Hai due "2" indici per la regione R2 e R3
Costas,

@Costas Questo è il problema: deve essere in grado di ricordare tutte le regioni per ciascun indice e trovare quella che corrisponde ai dati total.txt.
Barmar,

1
Questo sarebbe meglio farlo in una lingua con array multidimensionali, come perlo php. Ogni indicatore indica una serie di regioni, ognuna con i propri valori alti e bassi. Quindi è possibile eseguire il ciclo attraverso l'array cercando l'area in cui il numero è compreso nell'intervallo.
Barmar,

@Costas Sì. Ecco dove rimango bloccato. Sebbene R2 e R3 siano regioni diverse, hanno lo stesso numero di indicatore. Non so come capirlo.
lumaca

@Barmar In tal caso, l'OP dovrebbe costruire un array sulla regione ma non sull'indice
Costas,

Risposte:


3

Gli indicatori in entrambi i file di input (la prima colonna) non sono univoci, quindi è difficile usarli come chiavi. Ma se gli ID regione sono univoci, possiamo usare quelli:

 $ awk 'FNR == NR { reg=$4; low[reg]=$2; high[reg]=$3; ind[reg]=$1; next} 
  { for (reg in ind) { 
      if ($1 == ind[reg] && $2 >= low[reg] && $2 <= high[reg]) {
         print $0,reg
      } } }' index.txt total.txt
1 423 R1
1 2342 R1
2 789 R2
2 5332 R3
2 6762 R3

Questo è fondamentalmente il tuo codice, con il ciclo for aggiunto per mappare le regioni ai loro indicatori e controllare quale delle linee nel secondo file corrisponde.

(per quanto riguarda 2 789 R2vs 2 809 R2, non sono sicuro del motivo per cui 809 dovrebbe essere stampato se i limiti sono 600 e 800.)

Modificare il comando di stampa in print $0,reg > reg ".txt"per ottenere l'output nei file denominati dalle regioni.


Grazie mille! @ilkkachu Dato che il risultato atteso è stato modificato dal mio, quindi è un errore. Hai ragione. Grazie ancora!
lumaca
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.