У меня есть несколько каталогов ("амазонка", "Нигер"...), в котором у меня есть несколько подкаталогов ("gfdl", "hadgem"...), в котором у меня также есть несколько подкаталогов ("rcp8p5", "rcp4p5"...). В этом длятся подкаталоги, у меня всегда есть две папки ("исторический", "спроектированный"), которые содержат тысячу таблиц, имеющих тот же кадр. Поэтому я хотел бы связать те таблицы (существующий в двух папках последних подкаталогов), чтобы иметь всего одну большую таблицу только с одним заголовком и не заголовком каждый раз, когда таблица была, конкатенируют. Кто-либо знает, как сделать это?
Я в настоящее время использую следующую циклическую структуру:
#!/bin/bash
# usage:cat_dat dirname
data_dir=/scratch/01/stevens/climate_scenario/river
for river in tagus
do
for gcm in gfdl-esm2m hadgem2-es
do
for scenario in rcp8p5 rcp4p5 rcp6p0 rcp2p6
do
find "${data_dir}/${river}/${gcm}/${scenario}" name \*.dat -exec cat {} + >> "${data_dir}/${river}/${gcm}/${scenario}.dat"
done
done
done
но я не могу избавиться от заголовка с этим! Любой помогает, значительно ценится!Спасибо!
Используя awk
в единственной папке
awk 'NR==1 {header=$_} FNR==1 && NR!=1 { $_ ~ $header getline; } {print}' *.dat > out
find
и awk
если Вам нужны все файлы в текущей папке и в подпапках. Можно заменить .
с Вашей желаемой папкой.
find . -type f -name "*.dat" -print0 | \
xargs -0 awk 'NR==1 {header=$_} FNR==1 && NR!=1 { $_ ~ $header getline; } {print}' > out
или, поскольку getline плох (спасибо @fedorqui)
find . -type f -name "*.dat" -exec awk 'NR==1 || FNR!=1' {} + ;
Пример
% cat foo1.dat
a b c
1 2 3
% cat foo2.dat
a b c
4 5 6
% awk 'NR==1 {header=$_} FNR==1 && NR!=1 { $_ ~ $header getline; } {print}' *.dat > out
% cat out
a b c
1 2 3
4 5 6
Можно использовать a while
цикл, который питается a find
через замену процесса:
d=0
while IFS= read -r file
do
[ "$d" -ge 1 ] && tail -n +2 "$file" || cat "$file"
(( d ++ ))
done < <(find "/dir/folder" name *.dat)
Таким образом, это выполнит a cat
на первом соответствии и tail -n +2
на остальных.
С другой стороны, если у Вас есть все файлы в том же dir, можно сказать:
awk 'FNR>1 || NR==1' files*
Это будет соответствовать всему кроме случая когда FNR==1
и NR>1
, то есть, все кроме заголовка файлов после первого. Почему? Поскольку NR
содержит количество считанной строки в целом, тогда как FNR
содержит количество строки текущего считанного файла.