[bash] join di 2 file ... ma join non mi funziona

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
Luke Skywalker
Prode Principiante
Messaggi: 21
Iscrizione: giovedì 7 gennaio 2016, 12:53
Sesso: Maschile

[bash] join di 2 file ... ma join non mi funziona

Messaggio da Luke Skywalker »

ho 2 file

file1.txt:
FP 429 0.047 0.047 0.040 54640 0.400 0.000
FP 440 0.184 0.184 0.093 6467 0.400 0.000
FP 448 0.306 0.306 0.250 6846 0.400 0.000
FP 451 0.101 0.101 0.040 7221 0.400 0.000
.
.

file2.txt:
427 596217.50 4865902.50
428 596232.50 4865902.50
429 596247.50 4865902.50
430 596262.50 4865902.50
.
.

con il comando joi ottengo:

join -1 2 -2 1 file1.txt file2.txt>>out.txt
join: file2.txt:10: is not sorted: 10 595632.50 4865887.50
join: file1.txt:89: is not sorted: FP 1143 0.400 0.400 0.330 121680 0.400 0.000

e non genera nessun file out.txt (nemmeno vuoto ... molto strano). Avrei dovuto ottenere un file del tipo :
FP 429 0.047 0.047 0.040 54640 0.400 0.000 596247.50 4865902.50

cioè quando trova che una riga del file1.txt ha uguale il contenuto della seconda colonna uguale al contenuto della prima colonna del file2.txt scrive nel file out.txt il join delle 2 righe.

Che cosa sbaglio? oppure c'è un'altro modo per fare questo?
TommyB1992
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 852
Iscrizione: domenica 7 luglio 2013, 15:55
Desktop: GNU/Linux
Distribuzione: Ubuntu 22.04.2 LTS
Sesso: Maschile

Re: [bash] join di 2 file ... ma join non mi funziona

Messaggio da TommyB1992 »

Non puoi semplicemente scrivere l'output su un file e poi accodare il successivo?
Luke Skywalker
Prode Principiante
Messaggi: 21
Iscrizione: giovedì 7 gennaio 2016, 12:53
Sesso: Maschile

Re: [bash] join di 2 file ... ma join non mi funziona

Messaggio da Luke Skywalker »

non capisco cosa intendi. Il comando join (come l'ho scritto) dovrebbe mettere l'output su un file ma non lo fa
Avatar utente
nuzzopippo
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1624
Iscrizione: giovedì 12 ottobre 2006, 11:34

Re: [bash] join di 2 file ... ma join non mi funziona

Messaggio da nuzzopippo »

prova con :

Codice: Seleziona tutto

join -1 2 file1.txt file2.txt
avrai questo output a video :

Codice: Seleziona tutto

429 FP 0.047 0.047 0.040 54640 0.400 0.000 596247.50 4865902.50
questo perchè indichi di considerare nel primo file(-1) il 2° campo

ATTENZIONE i dati devono essere ordinati, altrimenti, supposto di sostituire 430 al 448 del file1 otterresti :

Codice: Seleziona tutto

429 FP 0.047 0.047 0.040 54640 0.400 0.000 596247.50 4865902.50
join: file1.txt:3: is not sorted: FP 430 0.306 0.306 0.250 6846 0.400 0.000
una volta ordinato in file1b.txt il file1 avremo :

Codice: Seleziona tutto

join -1 2 file1b.txt file2.txt -o auto
429 FP 0.047 0.047 0.040 54640 0.400 0.000 596247.50 4865902.50
430 FP 0.306 0.306 0.250 6846 0.400 0.000 596262.50 4865902.50
Per impostare l'output che vuoi ottenere, devi utilizzare l'opzione -o "stringaformato" ove stringaformato è la sequenza "numerofile.numerocampo", esempio:

Codice: Seleziona tutto

join -1 2 file1b.txt file2.txt -o "1.1 1.2 1.3 2.2 2.3"
FP 429 0.047 596247.50 4865902.50
FP 430 0.306 596262.50 4865902.50
ove estraggo il 1°, 2° e 3° campo dal primo file ed il 2° e 3° dal secondo file.
Per maggiori dettagli : join --help

Ovviamente l'output può essere reindirizzato dove vuoi

[Edit] dimenticavo : l'ordinamento dei dati è essenziale, evidentemente se non ha prodotto niente non ha trovato dati prima dell'eccezione dovuta al cattivo ordinamento, effettuando il Tuo comando (che equivale alla forma abbreviata da me posta) viene registrata la sola prima riga di output, l'eccezione no, gli esempi sono basati sulle sole linee dati da Te indicate, ed erano per indicare proprio questo comportamento che ho riscontrato ... che, ovviamente, nella foga del discorso ho tralasciato :lol:

[Ri-Edit] fatto un po' di prove 'sta mattina, fermo restando l'impostazione negli esempi sopra, potresti ordinare i files nella esecuzione del comando ordinandoli contestualmente così:

Codice: Seleziona tutto

join -1 2 <(sort file1.txt) <(sort file2.txt) -o "1.1 1.2 1.3 2.2 2.3"
ovviamente, potrai reindirizzare l'output dove vuoi
Fatti non foste a viver come bruti ...
Luke Skywalker
Prode Principiante
Messaggi: 21
Iscrizione: giovedì 7 gennaio 2016, 12:53
Sesso: Maschile

Re: [bash] join di 2 file ... ma join non mi funziona

Messaggio da Luke Skywalker »

il problema è questo:

1.txt:
9 bc
10 ab
11 d

2.txt:
1 001a
10 010a
11 011a
12 012a

$ join 1.txt 2.txt
join: 1.txt:2: is not sorted: 10 ab

il problema è che join non fa il sort numerico ma probabilmente alfabetico, infatti dice che nel primo file 10 is not sorted e si ferma ... invece numericamente è corretto perchè è sotto 9 e sopra 11.
C'è un modo per dire a joi di fare un sort numerico? oppure c'è un'altro modo per fare questo?
Avatar utente
nuzzopippo
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1624
Iscrizione: giovedì 12 ottobre 2006, 11:34

Re: [bash] join di 2 file ... ma join non mi funziona

Messaggio da nuzzopippo »

Vi è già la risposta nel precedente post, comunque ...

Puoi ottenere solo i campi comuni, posto :
file1.txt contenente :

Codice: Seleziona tutto

9 bc
10 ab
11 d
file2.txt contenente :

Codice: Seleziona tutto

1 001a
10 010a
11 011a
12 012a
Puoi estrarre i campi con 10 e 11, ordinandoli indipendentemente da "cosa" sono, con il comando :

Codice: Seleziona tutto

join <(sort file1.txt) <(sort file2.txt) -o "1.1 1.2 2.2"
l'output sarà :

Codice: Seleziona tutto

10 ab 010a
11 d 011a
Se occorre "altro" sii più preciso, si può vedere tra le opzioni di join, ho visto come funziona per curiosità, o tramite script o altro, per manipolare i dati esistono molti metodi e nella sezione circola gente molto più brava di me, chiarezza sul problema e la risposta la avrai ;)

[Edit] giacché ho una mezz'ora libera ... guardando le opzioni

Codice: Seleziona tutto

  -a FILENUM        also print unpairable lines from file FILENUM, where
                      FILENUM is 1 or 2, corresponding to FILE1 or FILE2
  -e EMPTY          replace missing input fields with EMPTY
  -i, --ignore-case  ignore differences in case when comparing fields
  -j FIELD          equivalent to '-1 FIELD -2 FIELD'
  -o FORMAT         obey FORMAT while constructing output line
  -t CHAR           use CHAR as input and output field separator
  -v NUMFILE        come -a NUMFILE, ma elimina le righe di output unite
  -1 CAMPO          unisce in questo CAMPO del file 1
  -2 CAMPO          unisce in questo CAMPO del file 2
e giocandoci un po', volendo avere l'output anche dei campi NON corrispondenti, si può utilizzare l'opzione "-a", e volendo indicare una stringa sostitutiva dei campi mancanti con "-e", tipo

Codice: Seleziona tutto

join -o 1.1,2.1,1.2,2.2 -e "==" -a 1 -a 2 <(sort file1.txt) <(sort file2.txt)
si avrebbe come output

Codice: Seleziona tutto

10 10 ab 010a
== 1 == 001a
11 11 d 011a
== 12 == 012a
9 == bc ==
vedi il metodo alternativo trovato per la formattazione di -o, esempi in rete ;)

Non mi sembra possibile utilizzare anche anche un ordinamento numerico, vedi la variante :

Codice: Seleziona tutto

join -o 1.1,2.1,1.2,2.2 -e "==" -a 1 -a 2 <(sort -n file1.txt) <(sort -n file2.txt)
che da

Codice: Seleziona tutto

== 1 == 001a
== 10 == 010a
== 11 == 011a
== 12 == 012a
9 == bc ==
join: /dev/fd/63:2: is not sorted: 10 ab
10 == ab ==
11 == d ==
non riconoscendolo da parte del join e, di conseguenza, dando dei problemi nell'output
Fatti non foste a viver come bruti ...
rai
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2842
Iscrizione: domenica 11 maggio 2008, 18:03
Desktop: plasma
Distribuzione: 22.04
Località: Palermo

Re: [bash] join di 2 file ... ma join non mi funziona

Messaggio da rai »

Luke Skywalker ha scritto:il problema è questo:

1.txt:
9 bc
10 ab
11 d

2.txt:
1 001a
10 010a
11 011a
12 012a

$ join 1.txt 2.txt
join: 1.txt:2: is not sorted: 10 ab

il problema è che join non fa il sort numerico ma probabilmente alfabetico, infatti dice che nel primo file 10 is not sorted e si ferma ... invece numericamente è corretto perchè è sotto 9 e sopra 11.
C'è un modo per dire a joi di fare un sort numerico? oppure c'è un'altro modo per fare questo?
Quello che chiedi qui ( e che non è esattamente la stessa cosa che avevi chiesto nel primo post ) si può fare più semplicemente con awk

Codice: Seleziona tutto

$ cat 1.txt 
9 bc
10 ab
11 d
$
$ cat 2.txt 
1 001a
10 010a
11 011a
$
$  awk 'FNR==NR {a[$1]=$0; next} { if ($1 in a) {print a[$1] " " $0}}' 2.txt 1.txt
10 010a 10 ab
11 011a 11 d
$
Se non corrisponde esattamente all'output che desideri sii più chiaro e lo si aggiusta ;)
Avatar utente
nuzzopippo
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1624
Iscrizione: giovedì 12 ottobre 2006, 11:34

Re: [bash] join di 2 file ... ma join non mi funziona

Messaggio da nuzzopippo »

Pensavo interessasse solo un discorso su join, un join ordinato numericamente era semplicissimo già con le istruzioni usate, bastava utilizzarlo come input di sort:

Codice: Seleziona tutto

sort -n <(join <(sort file1.txt) <(sort file2.txt) -o "1.1 1.2 2.2")
10 ab 010a
11 d 011a

 sort -n <(join -a1 -a2 <(sort file1.txt) <(sort file2.txt))
1 001a
9 bc
10 ab 010a
11 d 011a
12 012a

Fatti non foste a viver come bruti ...
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 11 ospiti