Объединение нескольких файлов на основе общего столбца

850
user1083096

У меня есть несколько файлов, каждый с двумя столбцами:

Например :

file1.txt

ID Value1 1 40 2 30 3 70 

file2.txt

ID Value2 3 50 4 70  9 20  

И так далее,

file1230.txt

ID Value150 9 98 10 52 2 71 

Как объединить эти файлы на основе первого столбца (на основе пересечений между файлами)? Мой вывод должен быть

ID Value1 Value2 Value150 1 40 0 0 2 30 0 71 3 70 50 0 4 0 70 0 9 0 20 98 10 0 0 52 

Может ли кто-нибудь помочь в этом, используя команды awk или Linux.

Спасибо.

1

2 ответа на вопрос

0
Stephen Rauch

Вот один из способов сделать это, используя python.

Код:

import sys  columns = [] data = {} ids = set() for filename in sys.argv[1:]: with open(filename, 'rU') as f: key = next(f).strip().split()[1] columns.append(key) data[key] = {} for line in f: if line.strip(): id, value = line.strip().split() try: data[key][int(id)] = value except ValueError as exc: raise ValueError( "Problem in line: '{}' '{}' '{}'".format( id, value, line.rstrip()))  ids.add(int(id))  print('\t'.join(['ID'] + columns))  for id in sorted(ids): line = [] for column in columns: line.append(data[column].get(id, '0')) print('\t'.join([str(id)] + line)) 

Результаты:

ID Value1 Value2 Value150 1 40 0 0 2 30 0 71 3 70 50 0 4 0 70 0 9 0 20 98 10 0 0 52 
Я не очень хорош в Python и не могу понять код. Хотите знать, как дать входные файлы. user1083096 6 лет назад 0
`sys.argv [1:]` возьмет все файлы из командной строки. Если вы сохранили вышеупомянутое как `my_file.py`, то` python my_file.py file1.txt file2.txt file3.txt` обработает 3 файла. Вы также можете заменить `sys.argv [1:]` на список, который вы создали. Stephen Rauch 6 лет назад 0
Спасибо ... но так как у меня более 1000 файлов, я дал команду python3 my_file.py * .txt, она показала ошибку user1083096 6 лет назад 0
Любая конкретная ошибка? Работало ли это с одним или двумя файлами? Что-нибудь еще, чтобы продолжить? Stephen Rauch 6 лет назад 0
Даже для двух файлов это показывает ту же ошибку user1083096 6 лет назад 0
В ваших данных есть что-то, что не соответствует вашим примерам. Я добавил некоторые сообщения об ошибках. Stephen Rauch 6 лет назад 0
0
Paulo

Решение Bash с инструментами командной строки. Список входных файлов был не в порядке, поэтому ls -vвывод cat.

while read line; do if [[ "$line" =~ ID ]]; then array=$ index+=($array) continue else eval $array'[$]=$' fi done <<<"$( cat $(ls -v file[0-9]*.txt) )"  printf ID for name in $; do printf ' %s' $name done echo  max_ind=$( sort -nu file[0-9]*.txt | tail -n1 | cut -d' ' -f1 )  for (( j = 1 ; j <= $max_ind ; j++ )); do for (( i = 0 ; i < ${#index[@]} ; i++ )); do value=$( eval 'echo ${'$'[j]}' ) roll+=$( [ "$value" ] && printf "%-${#index[i]}s " $value || printf "%-${#index[i]}s " 0 ) done [[ "$roll" =~ [^0\ ] ]] && printf '%-4s%s\n' $j "$roll" unset roll done 

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