If the files are all in the same dir, you can:
ls |
awk -F_ '{ i=$1; m=$2; s=$3; f[i"_"s] = f[i"_"s] " " $0 }
END{ for(insc in f)
printf "paste%s >out_%s.txt\n",f[insc],insc
}'
which splits the filename on "_" (-F_
), sets the variables i,m,s
to the first 3 parts of the filename (institute,model,scenario),
and accumulates in array f the filename. The array is indexed
only by the institute and scenario, so all the models are concatenated
(m isn't used). The final END prints the f array, and uses the index (institute_scenario) as the
name for the output file. With your examples this produces
paste wbm_gfdl_rcp8p5_mississippi.txt wbm_hadgem_rcp8p5_mississippi.txt >out_wbm_rcp8p5.txt
paste matsiro_hadgem_rcp4p5_mississippi.txt matsiro_ipsl_rcp4p5_mississippi.txt >out_matsiro_rcp4p5.txt
paste matsiro_gfdl_rcp8p5_mississippi.txt matsiro_miroc_rcp8p5_mississippi.txt >out_matsiro_rcp8p5.txt
You then need to pipe this into the shell to have it executed. Add | sh
to the last line above to do this.
To remove some columns from the input files, you need to alter the awk line
that is collecting all the input filenames. In the 1st awk line:
{ i=$1; m=$2; s=$3; f[i"_"s] = f[i"_"s] " " $0 }
the filename is the "$0". For example, if you change this line into:
{ i=$1; m=$2; s=$3; f[i"_"s] = f[i"_"s] sprintf(" <(cut -f4 %s)",$0) }
then you will get the example output:
paste <(cut -f4 wbm_gfdl_rcp8p5_mississippi.txt) <(cut -f4 wbm_hadgem_rcp8p5_mississippi.txt) >out_wbm_rcp8p5.txt
but if you want to cut only the 2nd filename, it is a bit more complicated and
you need this instead:
{ i=$1; m=$2; s=$3;
if(f[i"_"s]=="")add = $0; else add = sprintf("<(cut -f4 %s)",$0);
f[i"_"s] = f[i"_"s] " " add }
so you will get
paste wbm_gfdl_rcp8p5_mississippi.txt <(cut -f4 wbm_hadgem_rcp8p5_mississippi.txt) >out_wbm_rcp8p5.txt
If sh
does not understand the syntax <(cut ...)
then replace it by bash
.
Best Answer
The
time
command itself is not capable of doing this directly. It does output a time in a fractional format, so it can be parsed back into milliseconds by multiplying by 1000:This means you can kinda make a command that does it via:
That's essentially parsing the output of
time
and multiplying it by 1000. It's a mess because, well, bash.Probably a better/more useful mess would be this script user Infineight posted on Stack Overflow:
This (I have expanded it for readability) saves the current nanosecond timestamp from
date
, runs the command, then does a subtraction to calculate the time elapsed and formats it into milliseconds.In my testing they both seemed to yield the same results.