Article View: es.comp.os.linux.programacion
Article #7472Re: Sacar columnas de valores de dos ficheros (para gnuplot)
From: Pascal Bourguignon
Date: Wed, 26 Feb 2003 19:35
Date: Wed, 26 Feb 2003 19:35
307 lines
9392 bytes
9392 bytes
Han Solo <hsolo@escomposlinux.org> writes:
> Hola a todos.
>
> Imaginemos que tengo dos ficheros, con columnas de datos
>
> fich.a
> 1 2 3 4 5 6 7
> 8 9 10 11 12 12 14
> . . . . . . .
> . . . . . . .
> . . . . . . .
>
>
> fich.b
> 15 16 27 18
> 20 21 22 23
> . . . .
> . . . .
> . . . .
>
> Se trata de sacar una (o varias) comlumnas completas de cada fichero y
> meterlas en otro. Con awk s� c�mo sacarlas, pero luego desconozco la
> manera de unirlas. He estado mirando la ayuda de join, pero creo que
> no hace lo que quiero. Los dos ficheros *tienen el mismo n�mero de
> l�neas*.
>
> En el fondo, esto es para dibujar unas gr�ficas con gnuplot, pero
> realizando operacioes entre columnas de distintos ficheros. Gnuplot lo
> permite para columnas del mismo fichero, pero no para columnas de
> ficheros distintos (o al menos no he visto c�mo en la doc de gnuplot)
>
> �alguna idea? (Me valdr�a la soluci�n para gnuplot directamente, si
> existe).
Puedes hacer todo con awk:
awk -v f1=fich.a -v c1=1 -v f2=fich.b -v c2=2 '
END{
r1=getline l1 < f1;
r2=getline l2 < f2;
while((r1>0)&&(r2>0)){
split(l1,a1);
split(l2,a2);
printf "%d %d\n",a1[c1],a2[c2];
r1=getline l1 < f1;
r2=getline l2 < f2;
}
}
' < /dev/null
Sino creo que hay un programa estandard para hacer eso, pero no me
acuerdo de su nombre. Hace tiempo, me habia hecho una peque�a
herramienta:
----(lcat.c)-------------------------------------------------------------------
/******************************************************************************
FILE: lcat.c
LANGUAGE: ANSI-C
SYSTEM: ANSI
USER-INTERFACE: ANSI
DESCRIPTION
Takes arguments files as input and writes to stdout lines made
of the concatenation of lines from each input files.
Example:
lcat - tete -L toto -T tata titi -e tutu -t! toto tyty
gives:
stdinline1teteline1
totoline1 tataline1 titiline1tutuline1!totoline1!tytyline1
stdinline2teteline2
totoline2 tataline2 titiline2tutuline2!totoline2!tytyline2
...
USAGE
lcat ( [ -L | -T | -tc | -t | -e ] file | - ) ...
-L use the new line character to separate output fields.
(this merges the input files line by line).
-T use the TAB character to separate output fields.
-tc use the character c to separate output fields.
-t use \0 to separate output fields.
-e (default) do not separate the output fields.
- stand for the stdin. Default does not read stdin.
AUTHORS
<PJB> Pascal J. Bourguignon
MODIFICATIONS
1993/10/10 <PJB> Creation.
BUGS
lines from input file may be no longer than 4*BUFSIZ.
LEGAL
GPL
Copyright Pascal J. Bourguignon 1993 - 1993
mailto:pjb@informatimago.com
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version
2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public
License along with this program; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
******************************************************************************/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
void usage(char* name)
{
printf("%s usage:\n\t%s [-T|-L|-t<c>|-e] [filename|-] ... "
"< stdin > stdout\n",name,name);
}/*usage;*/
#define linesize (4*BUFSIZ)
#define sepnone '\0'
#define septhis '\1'
int main(int argc,char** argv)
{
int i;
int ffirst;
int flast;
int ocount;
typedef struct {
FILE* file;
char dosep;
char separator;
} FDescT;
FDescT* input;
char buffer[linesize];
input=malloc(sizeof(FDescT)*(argc+1));
if(input==NULL){
sprintf(buffer,"%s fatal error: allocating argument descriptors:",
argv[0]);
perror(buffer);
return(1);
}
input[0].file=stdin;
input[0].dosep=sepnone;
input[0].separator='\0';
ffirst=1;
flast=1;
i=1;
while(i<argc){
if(strcmp("-T",argv[i])==0){
input[flast-1].dosep=septhis;
input[flast-1].separator='\t';
input[flast].dosep=septhis;
input[flast].separator='\t';
}else if(strcmp("-L",argv[i])==0){
input[flast-1].dosep=septhis;
input[flast-1].separator='\n';
input[flast].dosep=septhis;
input[flast].separator='\n';
}else if(strcmp("-e",argv[i])==0){
input[flast-1].dosep=sepnone;
input[flast-1].separator='\0';
input[flast].dosep=sepnone;
input[flast].separator='\0';
}else if(strncmp("-t",argv[i],2)==0){
input[flast-1].dosep=septhis;
input[flast-1].separator=argv[i][2];
input[flast].dosep=septhis;
input[flast].separator=argv[i][2];
}else if(strcmp("-",argv[i])==0){
ffirst=1;
input[flast].dosep=input[flast-1].dosep;
input[flast].separator=input[flast-1].separator;
input[flast].file=stdin;
flast++;
input[flast].dosep=septhis;
input[flast].separator='\n';
}else if(strncmp("-",argv[i],1)==0){
usage(argv[0]);
return(1);
}else{
input[flast].dosep=input[flast-1].dosep;
input[flast].separator=input[flast-1].separator;
input[flast].file=fopen(argv[i],"r");
if(input[flast].file==NULL){
sprintf(buffer,"%s warning: cannot open the file '%s'",
argv[0],argv[i]);
perror(buffer);
}else{
flast++;
input[flast].dosep=septhis;
input[flast].separator='\n';
}
}
i++;
}
ocount=flast-ffirst;
while(ocount>0){
i=ffirst;
while(i<flast){
if(input[i].file!=NULL){
char* r=fgets(buffer,linesize,input[i].file);
if(r==NULL){
fclose(input[i].file);
input[i].file=NULL;
ocount--;
}else{
int l=strlen(buffer);
if(buffer[l-1]=='\n'){
buffer[l-1]='\0';
}
fprintf(stdout,"%s",buffer);
}
}
if(input[i].dosep==septhis){
fprintf(stdout,"%c",input[i].separator);
}
i++;
}
if(input[i].dosep==septhis){
fprintf(stdout,"%c",input[i].separator);
}
}
free(input);
return(0);
}
----(lcat.1)-------------------------------------------------------------------
.TH LCAT 1 local
.SH NAME
lcat \- line catenate
.SH SYNOPSIS
.B lcat
\( [ \-L | \-T | \-tc | \-t | \-e ]
.I file
| - ) ...
.SH DESCRIPTION
.I lcat
takes arguments files as input and writes to stdout lines made
of the concatenation of lines from each input files.
.RS
.TP
\-L
use the new line character to separate output fields.
(this merges the input files line by line).
.TP
\-T
use the TAB character to separate output fields.
.TP
\-t
.I c
use the character
.I c
to separate output fields.
.TP
\-t
use \\0 to catenate output fields.
.TP
\-e
(default) do not separate the output fields.
.TP
\-
stand for the stdin. Default does not read stdin.
.sp
For example:
.sp
lcat - tete -L toto -T tata titi -e tutu -t! toto tyty
.sp
gives:
.RE
stdinline1teteline1
totoline1 tataline1 titiline1tutuline1!totoline1!tytyline1
stdinline2teteline2
totoline2 tataline2 titiline2tutuline2!totoline2!tytyline2
.SH FILES
none.
.SH SEE ALSO
.IR lcut (1)
.IR ldiff (1)
.br
.SH DIAGNOSTICS
``Self explanatory.''
.SH BUGS
One cannot easily add a seperator character at the begining of the output lines.
.SH AUTHOR
Pascal J. Bourguignon
... ha!
-------------------------------------------------------------------------------
> Emacs is not on every system
>
> So what? [...] Do you tell your administrative people to stick with
> notepad.exe? Do you tell your fat kids they can only have the crummy
> games that come with their video games or plain dress that comes with
> Barbie?
--
__Pascal_Bourguignon__ http://www.informatimago.com/
----------------------------------------------------------------------
There is a fault in reality. Do not adjust your minds. -- Salman Rushdie
Technical Details
Message-ID:
<87n0kideci.fsf@thalassa.informatimago.com>Path:
arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!newsfeed.stanford.edu!news-spur1.maxwell.syr.edu!news.maxwell.syr.edu!fu-berlin.de!uni-berlin.de!213.220.35.225!not-for-mailReferences:
<86r89u3nvs.fsf@ietcc.csic.es>Show Full Headers
Complete Article Headers
X-Google-Language: SPANISH,ASCII X-Google-Thread: f86c8,98a4c83b201651a5 X-Google-Attributes: gidf86c8,public X-Google-ArrivalTime: 2003-02-26 11:36:07 PST Path: arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!newsfeed.stanford.edu!news-spur1.maxwell.syr.edu!news.maxwell.syr.edu!fu-berlin.de!uni-berlin.de!213.220.35.225!not-for-mail From: Pascal Bourguignon <pjb@informatimago.com> Newsgroups: es.comp.os.linux.programacion Subject: Re: Sacar columnas de valores de dos ficheros (para gnuplot) Date: 26 Feb 2003 20:35:57 +0100 Organization: informatimago.com Lines: 307 Sender: pascal@thalassa.informatimago.com Message-ID: <87n0kideci.fsf@thalassa.informatimago.com> References: <86r89u3nvs.fsf@ietcc.csic.es> NNTP-Posting-Host: 213.220.35.225 Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit X-Trace: fu-berlin.de 1046288165 56502714 213.220.35.225 (16 [41911]) User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3.50