Mám několik souborů (tabulek) pojmenovaných jako:institute _
model _
scénář _
řeka .txt
(ústav , model , scénář a řeka jsou proměnné.) Chtěl bych vytvořit for
smyčka, která identifikuje všechny soubory, které mají stejný institut název a zároveň stejný scénář název, aby bylo možné připojit výsledky každého jiného modelu ve stejném výstupním souboru pomocí následujícího příkazu:
paste filename1.txt filename2.txt > output_file.txt
Vím, jak vytvořit for
smyčka přes jinou složku, ale ne přes názvy souborů. Má někdo nějaký nápad?
Jako minimální příklad mohou být názvy souborů následující:
wbm_gfdl_rcp8p5_mississippi.txt
wbm_hadgem_rcp8p5_mississippi.txt
matsiro_gfdl_rcp8p5_mississippi.txt
matsiro_ipsl_rcp4p5_mississippi.txt
matsiro_hadgem_rcp4p5_mississippi.txt
matsiro_miroc_rcp8p5_mississippi.txt
Potom bych chtěl připojit následující soubory:
wbm_gfdl_rcp8p5_mississippi.txt with
wbm_hadgem_rcp8p5_mississippi.txt
matsiro_ipsl_rcp4p5_mississippi.txt with
matsiro_hadgem_rcp4p5_mississippi.txt
matsiro_gfdl_rcp8p5_mississippi.txt with
matsiro_miroc_rcp8p5_mississippi.txt
Přijatá odpověď:
Pokud jsou všechny soubory ve stejném adresáři, můžete:
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
}'
který rozdělí název souboru na „_“ (-F_
), nastaví proměnné i,m,s
na první 3 části názvu souboru (institut,model,scenario),
a akumuluje je v poli f názvu souboru. Pole je indexováno
pouze institutem a scénářem, takže všechny modely jsou zřetězené
(m se nepoužívá). Poslední END vytiskne pole f a použije index (scénář_instituce) jako
název výstupního souboru. S vašimi příklady to vytváří
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
Pak to musíte přenést do shellu, aby se to provedlo. Přidat | sh
na poslední řádek výše.
Chcete-li odstranit některé sloupce ze vstupních souborů, musíte změnit řádek awk
, který shromažďuje všechny vstupní názvy souborů. V 1. řádku awk:
{ i=$1; m=$2; s=$3; f[i"_"s] = f[i"_"s] " " $0 }
název souboru je „$0“. Pokud například změníte tento řádek na:
{ i=$1; m=$2; s=$3; f[i"_"s] = f[i"_"s] sprintf(" <(cut -f4 %s)",$0) }
pak dostanete příklad výstupu:
paste <(cut -f4 wbm_gfdl_rcp8p5_mississippi.txt) <(cut -f4 wbm_hadgem_rcp8p5_mississippi.txt) >out_wbm_rcp8p5.txt
ale pokud chcete vyjmout pouze 2. název souboru, je to trochu složitější a
místo toho potřebujete toto:
{ 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 }
takže dostanete
paste wbm_gfdl_rcp8p5_mississippi.txt <(cut -f4 wbm_hadgem_rcp8p5_mississippi.txt) >out_wbm_rcp8p5.txt
Pokud sh
nerozumí syntaxi <(cut ...)
pak jej nahraďte bash
.