Свяжите несколько файлов без заголовка

У меня есть несколько каталогов ("амазонка", "Нигер"...), в котором у меня есть несколько подкаталогов ("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

но я не могу избавиться от заголовка с этим! Любой помогает, значительно ценится!Спасибо!

2
задан 22 November 2015 в 23:56

2 ответа

Используя 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
3
ответ дан 2 December 2019 в 01:58

Можно использовать 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 содержит количество строки текущего считанного файла.

2
ответ дан 2 December 2019 в 01:58

Другие вопросы по тегам:

Похожие вопросы: