Build table – добавить столбец в зависимости от имени файла

У меня есть огромное количество файлов, имеющих следующий стиль именования:

WBM_MIROC_rcp8p5_mississippi.txt WBM_GFDL_rcp8p5_nosoc_mississippi.txt DBH_HADGEM_rcp4p5_co2_mississippi.txt HMH_IPSL_rcp4p5_mississippi.txt 

Эти файлы представляют таблицы с (некоторые из них имеют разделитель табуляции и другой разделитель пробелов):

 YEAR MONTH DAY RES 1971 1 1 1988 1971 1 2 3829 ... 

Я хотел бы сгруппировать все файлы с rcp8p5 в их имени в одной большой таблице; и сделать то же самое для файлов с rcp4p5 в их имени. Но я просто хочу вставить 4 столбца каждого файла, чтобы избежать избыточности первых трех столбцов, которые всегда одинаковы. В настоящее время я использую следующий скрипт:

 ls | awk -F_ '{ i=$1; m=$2; s=$3; u=$4; if(f[s]=="")add = $0; else add = sprintf("<(cut -f4 %s)",$0); f[s] = f[s] " " add } END{ for(insc in f) printf "paste%s > out_%s.txt\n",f[insc],insc }' |bash 

Непонятно, почему, но выход не так, как ожидалось. У меня есть следующий вывод:

 YEAR MONTH DAY RES YEAR MONTH DAY RES YEAR MONTH DAY RES 1971 1 1 187 1971 1 1 143 1971 1 1 234 1971 1 2 321 1971 1 2 398 1971 1 1 754 ... 

Вместо этого я хотел бы получить следующий вывод:

 YEAR MONTH DAY RES RES RES 1971 1 1 187 143 234 1971 1 2 321 398 754 

Это может быть здорово, если кто-нибудь сможет дать мне подсказку!

  • Объединить и добавить столбцы для более чем двух файлов
  • UNIX вставляют столбцы и вставляют нули для всех отсутствующих значений
  • Вставить различные файлы csv
  • Формат ширины столбца с Printf
  • Как объединить несколько файлов на основе метки времени
  • нужна помощь с awk, объединяющим строки по последовательности из нескольких файлов в один файл
  • Объединение альтернативных строк из двух файлов
  • Как добавить текст из одной строки в конец другого?
  • 4 Solutions collect form web for “Build table – добавить столбец в зависимости от имени файла”

    Наиболее вероятный ответ заключается в том, что ваши столбцы файла данных не разделены вкладками, а, например, пробелом. Вы можете проверить это, выполнив один из них через cat -vet который показывает реальные вкладки как ^I

    Чтобы изменить команду cut для использования пробела в качестве разделителя, вам нужно добавить arg -d' ' , но поскольку вы уже находитесь в одинарных кавычках и awk-скрипте, вам нужно изменить свой sprintf(...) на

     sprintf("<(cut -d\" \" -f4 %s)",$0) 

    Для не слишком больших файлов:

     while read -r f_part do awk ' BEGIN{ SUBSEP=" " } NR==1{ for(i=2;i<ARGC;i++) $(NF+1)=$NF print } FNR==1{ next } { RES[$1,$2,$3]=RES[$1,$2,$3] $4 " " } END{ for(i in RES) print i, RES[i] }' *_${f_part}_* > big_table_${f_part} done < <(printf '%s\n' *_*_*_*txt | cut -d_ -f3 | sort -u) 

    Или если вы уверены в правильном порядке в файлах:

     while read -r f_part do set -- *_${f_part}_* sed -i 's/\s+/:/3;s/\s\+/\t/g;s/\s*$//' "$@" while [ $# -gt 1 ] do join -t: $1 $2 > tmp mv tmp big_table_${f_part} shift 2 set -- big_table_${f_part} "$@" done sed 's/:/\t/g' big_table_${f_part} done < <(printf '%s\n' *_*_*_*txt | cut -d_ -f3 | sort -u) 
     for f in rcp8p5 rcp4p5 do : >"$f.txt" find . ! -name . -prune ! -type d -name "*_${f}_*txt" -exec \ sh -c ' printf "%s\t" YEAR MONTH DAY printf "%.0sRES\t" "$@"; echo sed -n " /^[0-9]/!d;p;:n n /^[0-9]/s/.*[[:blank:]]//p bn " "$@" | paste ' -- {} + >>"$f.txt" done 

    … Я думаю, что у меня могло возникнуть неправильное представление о том, что вы делали раньше, и, возможно, это может компенсировать это. Я не уверен, что это сработает, но если это произойдет, это будет быстрее, чем то, что вы делаете.

    В основном find захватывает список файлов с именами, соответствующими любому из ...8... или ...4... и передает их {} + в оболочку.

    Оболочка печатает строку заголовка, начинающуюся с YEAR MONTH DAY за которой следует a \t ab и после печати столько столбцов RES что и аргументы.

    После этого sed объединяет все аргументы файла в один поток и печатает первую строку, начинающуюся с цифры в полном объеме, и все эти строки, начинающиеся с цифры, которая появляется после получения только последнего поля.

    Весь вывод sed передается в paste , который заменяет все \n ewlines на своем входе с \t abs на выходе.

    Надеюсь, эта версия будет работать, потому что вызов новой подоболочки и открытие нового канала для каждого файла в вашем списке – довольно ужасная идея.

    Если это произойдет, это, однако, сделает новую строку в вашей таблице для каждой группы файлов ARGMAX – что может быть не плохо, но с этим легко справиться.

    Вы также можете сделать что-то вроде

     arr=( *_rcp8p5_*.txt ) paste "${arr[@]}" | cut -f-4,$(seq -s, 8 4 $((4*${#arr[@]}))) >out_rcp8p5.txt 

    Это paste все *_rcp8p5_*.txt файлы, затем извлекает поля 1-4 и каждое четвертое поле после.

    Interesting Posts

    Неанглийские буквы в html2text?

    Запишите переменную, содержащую большой текст, с \ n в файл с обычными интерпретаторами интерпретаторов. Как ты делаешь это?

    Команда для генерации / dev / disk / -by-path / name в системе без денона udev

    Множественное сопоставление столбцов и настройка с помощью awk

    Изменение времени изменения файла для доступа к времени в массовом порядке

    Неверное соответствие уровня HTOP с хорошей командой?

    Выполнить скрипт в Syslinux

    Некоторые сообщения ICMP-ответа не поступают в пространство пользователя в последних ядрах

    сменить локальную группировку

    Почему `at` предупреждает меня, что команды будут выполняться с помощью / bin / sh? Что делать, если я хочу другую оболочку?

    мышь распознана как клавиатура xinput (Fedora 22)

    sed – найти строку и добавить

    Как установить переменную среды для sudo в MacOS?

    Удалите все слова перед определенным шаблоном, после другого шаблона

    Обновление Slackware Upgrade на новой версии

    Linux и Unix - лучшая ОС в мире.