🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: es.comp.os.linux.programacion
Article #7472

Re: Sacar columnas de valores de dos ficheros (para gnuplot)

#7472
From: Pascal Bourguignon
Date: Wed, 26 Feb 2003 19:35
307 lines
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-mail
References: <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