Как объединить файлы с разделителями табуляции?

У меня есть 3 файла с разделителями табуляции, как показано ниже:

Файл 1:

1   Hhe.7
2   Hpyl.1
10  Hac.2

Файл 2:

3   Hac.2
15  Hpyl.1
33  Hhe.7

Файл 3:

70  Hpyl.1
23  Hhe.7
9   Hac.2

Как объединить эти файлы (используя командную строку) в один файл, чтобы получить следующий вывод:

1  33  23  Hhe.7
2  15  70  Hpyl.1
10  3  9  Hac.2
3
задан 13.04.2016, 00:11

5 ответов

В маленьком сценарии Python можно объединиться неограниченный количество файлов:

#!/usr/bin/env python3
import sys

#read the files, split the lines for reordering
lines = sum([[l.strip().split() for l in open(f).readlines()]\
             for f in sys.argv[1:]], [])
# get the unique last sections
values = set(map(lambda x:x[1], lines))
# combine them with the combined first sections
newlist = [[y[0] for y in lines if y[1]==x]+[x] for x in values]
for l in newlist:
    print(("\t").join(l))

Копия это в пустой файл, сохраните его как merge.py, выполните его командой:

python3 /path/to/merge.py file1, file2, file3 (file4, file5 etc.)

Вывод на Ваших файлах в качестве примера:

10  3   9   Hac.2
1   33  23  Hhe.7
2   15  70  Hpyl.1

Добавление большего количества файлов

, Как упомянуто, количество файлов в принципе неограниченно, если я добавляю 4-й файл:

40   Hhe.7
50   Hpyl.1
60   Hac.2

и выполненный команда:

python3 /path/to/merge.py file1, file2, file3, file4

вывод будет:

40  23  33  1   Hhe.7
50  70  15  2   Hpyl.1
60  9   3   10  Hac.2
1
ответ дан 29.09.2019, 18:50
  • 1
    @kos можно сделать неограниченные файлы с остротой: awk '{a[$NF]=$1"\t"a[$NF];} END{for(i in a){print a[i],i}}' file1 file2 file3 fileN – Matt 13.04.2016, 01:33

Классическим инструментом UNIX для этого является join:

NAME
       join - join lines of two files on a common field

SYNOPSIS
       join [OPTION]... FILE1 FILE2

DESCRIPTION
       For  each  pair of input lines with identical join fields, write a line
       to standard output.  The default join field is the first, delimited  by
       blanks.

Тем не менее, join i) необходимо отсортировать входные данные для работы, и ii) может работать только с 2 файлами. Таким образом, вы можете сделать что-то уродливое и не элегантное, например:

  1. Сортировать каждый файл во втором поле и сохранить как новый файл

    sort -k2 file1 > sorted1
    sort -k2 file2 > sorted2
    sort -k2 file3 > sorted3
    
  2. [1118 ] Объедините файлы 1 и 2 в новый файл, а затем присоедините третий

    $ join -j2 --nocheck-order sorted1 sorted2 > newfile
    $ join -o 1.2,1.3,2.1,1.1  -1 1 -2 2 --nocheck-order newfile sorted3 
    10 3 9 Hac.2
    1 33 23 Hhe.7
    2 15 70 Hpyl.1
    

    Используемые опции:

       -1 FIELD
              join on this FIELD of file 1
    
       -2 FIELD
              join on this FIELD of file 2
       -j FIELD
              equivalent to '-1 FIELD -2 FIELD'
    
       --nocheck-order
              do not check that the input is correctly sorted
    
       -o FORMAT
              obey FORMAT while constructing output line
       FORMAT is one or more  comma  or  blank  separated
       specifications, each being 'FILENUM.FIELD' or '0'. 
    

    Таким образом, эта команда присоединится к 1-му полю поля. первый файл и 2-е поле второго файла, и будет напечатано 2-е поле первого файла (1.2), затем третье поле первого файла (1.3), первое поле второго файла ([ 1110]) и 1-е поле первого файла (1.1).

В качестве альтернативы, вы можете объединить все это в одну великолепно сложную команду:

$ join -o 1.1,2.2,2.3,2.1 -1 2 -2 1  --nocheck-order <(sort -k2 file3) \
      <(join -j2  --nocheck-order <(sort -k2 file1) <(sort -k2 file2)) 
9 10 3 Hac.2
23 1 33 Hhe.7
70 2 15 Hpyl.1

Если вам не нравится тайная командная строка-fu, вы всегда можете использовать небольшой скрипт:

$ awk '{a[$NF]=$1"\t"a[$NF];} END{for(i in a){print a[i],i}}' file{1,2,3} 
23  33  1    Hhe.7
9   3   10   Hac.2
70  15  2    Hpyl.1
4
ответ дан 29.09.2019, 18:50

С awk:

awk -F"\t" -v OFS="\t" '!(a[$2]){a[$2]=$1;next}
{a[$2]=a[$2]"\t"$1} 
END{
for ( i in a) {
    print a[i],i
    }
}'
1
ответ дан 29.09.2019, 18:50

Это - задание для join, который может присоединиться на общих полях двух файлов:

$ join -11 -22 -o1.2,1.3,2.1,0 <(join -j2 <(sort -k2,2 f1.txt) <(sort -k2,2 f2.txt)) <(sort -k2,2 f3.txt)
10 3 9 Hac.2
1 33 23 Hhe.7
2 15 70 Hpyl.1

Как join берет только два входных файла за один раз, мы использовали замену процесса (<()) для передачи вывода join - луг сначала два файла с третьим.

3
ответ дан 29.09.2019, 18:50

Ответ от:

Стопки Linux следующий сценарий должен сделать внешнее объединение на столбце (поле) 1 всех файлов с разделением табуляцией, передал как аргументы. Это использует соединение команда, которая делает внешнее объединение на отсортированных файлах, 2 файла за один раз.

Это присоединится к каждой строке в файлах, включая строки заголовка. Если Вы хотите, чтобы заголовки были исключены, изменились два sort команды к чему-то, что производит отсортированный файл, который опускает их.

#!/bin/sh
if test $# -lt 2
then
    echo usage: gjoin file1 file2 ...
    exit 1
fi
sort -t  

, Если у Вас есть более старая оболочка, , не будет заменен вкладкой, таким образом, необходимо будет использовать ' ВКЛАДКА ' , куда Вы помещаете литеральную вкладку между кавычками.

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

sort -t  

могут быть заменены [1 115]

join -1 1 -2 1 -t  
\t', не будет заменен вкладкой, таким образом, необходимо будет использовать ' ВКЛАДКА ' , куда Вы помещаете литеральную вкладку между кавычками.

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' result <(sort -t \t', не будет заменен вкладкой, таким образом, необходимо будет использовать ' ВКЛАДКА ' , куда Вы помещаете литеральную вкладку между кавычками.

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' -k 1 "$f") > newresult \t', не будет заменен вкладкой, таким образом, необходимо будет использовать ' ВКЛАДКА ' , куда Вы помещаете литеральную вкладку между кавычками.

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' -k 1 "$f" > temp join -1 1 -2 1 -t

могут быть заменены [1 115]

join -1 1 -2 1 -t  \t', не будет заменен вкладкой, таким образом, необходимо будет использовать '   ВКЛАДКА  ' , куда Вы помещаете литеральную вкладку между кавычками. 

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' result <(sort -t \t', не будет заменен вкладкой, таким образом, необходимо будет использовать ' ВКЛАДКА ' , куда Вы помещаете литеральную вкладку между кавычками.

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' -k 1 "$f") > newresult

\t', не будет заменен вкладкой, таким образом, необходимо будет использовать ' ВКЛАДКА ' , куда Вы помещаете литеральную вкладку между кавычками.

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' result temp > newresult

могут быть заменены [1 115]

join -1 1 -2 1 -t  \t', не будет заменен вкладкой, таким образом, необходимо будет использовать '   ВКЛАДКА  ' , куда Вы помещаете литеральную вкладку между кавычками. 

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' result <(sort -t \t', не будет заменен вкладкой, таким образом, необходимо будет использовать ' ВКЛАДКА ' , куда Вы помещаете литеральную вкладку между кавычками.

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' -k 1 "$f") > newresult

\t', не будет заменен вкладкой, таким образом, необходимо будет использовать ' ВКЛАДКА ' , куда Вы помещаете литеральную вкладку между кавычками.

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' -k 1 "$1" > result shift for f in "$@" do sort -t

, Если у Вас есть более старая оболочка, , не будет заменен вкладкой, таким образом, необходимо будет использовать ' ВКЛАДКА ' , куда Вы помещаете литеральную вкладку между кавычками.

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

sort -t  

могут быть заменены [1 115]

join -1 1 -2 1 -t  \t', не будет заменен вкладкой, таким образом, необходимо будет использовать '   ВКЛАДКА  ' , куда Вы помещаете литеральную вкладку между кавычками. 

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' result <(sort -t \t', не будет заменен вкладкой, таким образом, необходимо будет использовать ' ВКЛАДКА ' , куда Вы помещаете литеральную вкладку между кавычками.

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' -k 1 "$f") > newresult

\t', не будет заменен вкладкой, таким образом, необходимо будет использовать ' ВКЛАДКА ' , куда Вы помещаете литеральную вкладку между кавычками.

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' -k 1 "$f" > temp join -1 1 -2 1 -t

могут быть заменены [1 115]

join -1 1 -2 1 -t  \t', не будет заменен вкладкой, таким образом, необходимо будет использовать '   ВКЛАДКА  ' , куда Вы помещаете литеральную вкладку между кавычками. 

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' result <(sort -t \t', не будет заменен вкладкой, таким образом, необходимо будет использовать ' ВКЛАДКА ' , куда Вы помещаете литеральную вкладку между кавычками.

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' -k 1 "$f") > newresult

\t', не будет заменен вкладкой, таким образом, необходимо будет использовать ' ВКЛАДКА ' , куда Вы помещаете литеральную вкладку между кавычками.

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' result temp > newresult

могут быть заменены [1 115]

join -1 1 -2 1 -t  \t', не будет заменен вкладкой, таким образом, необходимо будет использовать '   ВКЛАДКА  ' , куда Вы помещаете литеральную вкладку между кавычками. 

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' result <(sort -t \t', не будет заменен вкладкой, таким образом, необходимо будет использовать ' ВКЛАДКА ' , куда Вы помещаете литеральную вкладку между кавычками.

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' -k 1 "$f") > newresult

\t', не будет заменен вкладкой, таким образом, необходимо будет использовать ' ВКЛАДКА ' , куда Вы помещаете литеральную вкладку между кавычками.

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' -k 1 "$f" > temp join -1 1 -2 1 -t

, Если у Вас есть более старая оболочка, , не будет заменен вкладкой, таким образом, необходимо будет использовать ' ВКЛАДКА ' , куда Вы помещаете литеральную вкладку между кавычками.

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

sort -t  

могут быть заменены [1 115]

join -1 1 -2 1 -t  \t', не будет заменен вкладкой, таким образом, необходимо будет использовать '   ВКЛАДКА  ' , куда Вы помещаете литеральную вкладку между кавычками. 

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' result <(sort -t \t', не будет заменен вкладкой, таким образом, необходимо будет использовать ' ВКЛАДКА ' , куда Вы помещаете литеральную вкладку между кавычками.

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' -k 1 "$f") > newresult

\t', не будет заменен вкладкой, таким образом, необходимо будет использовать ' ВКЛАДКА ' , куда Вы помещаете литеральную вкладку между кавычками.

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' -k 1 "$f" > temp join -1 1 -2 1 -t

могут быть заменены [1 115]

join -1 1 -2 1 -t  \t', не будет заменен вкладкой, таким образом, необходимо будет использовать '   ВКЛАДКА  ' , куда Вы помещаете литеральную вкладку между кавычками. 

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' result <(sort -t \t', не будет заменен вкладкой, таким образом, необходимо будет использовать ' ВКЛАДКА ' , куда Вы помещаете литеральную вкладку между кавычками.

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' -k 1 "$f") > newresult

\t', не будет заменен вкладкой, таким образом, необходимо будет использовать ' ВКЛАДКА ' , куда Вы помещаете литеральную вкладку между кавычками.

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' result temp > newresult

могут быть заменены [1 115]

join -1 1 -2 1 -t  \t', не будет заменен вкладкой, таким образом, необходимо будет использовать '   ВКЛАДКА  ' , куда Вы помещаете литеральную вкладку между кавычками. 

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' result <(sort -t \t', не будет заменен вкладкой, таким образом, необходимо будет использовать ' ВКЛАДКА ' , куда Вы помещаете литеральную вкладку между кавычками.

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' -k 1 "$f") > newresult

\t', не будет заменен вкладкой, таким образом, необходимо будет использовать ' ВКЛАДКА ' , куда Вы помещаете литеральную вкладку между кавычками.

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' result temp > newresult mv newresult result done cat result rm result temp

, Если у Вас есть более старая оболочка, , не будет заменен вкладкой, таким образом, необходимо будет использовать ' ВКЛАДКА ' , куда Вы помещаете литеральную вкладку между кавычками.

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

sort -t  

могут быть заменены [1 115]

join -1 1 -2 1 -t  \t', не будет заменен вкладкой, таким образом, необходимо будет использовать '   ВКЛАДКА  ' , куда Вы помещаете литеральную вкладку между кавычками. 

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' result <(sort -t \t', не будет заменен вкладкой, таким образом, необходимо будет использовать ' ВКЛАДКА ' , куда Вы помещаете литеральную вкладку между кавычками.

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' -k 1 "$f") > newresult

\t', не будет заменен вкладкой, таким образом, необходимо будет использовать ' ВКЛАДКА ' , куда Вы помещаете литеральную вкладку между кавычками.

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' -k 1 "$f" > temp join -1 1 -2 1 -t

могут быть заменены [1 115]

join -1 1 -2 1 -t  \t', не будет заменен вкладкой, таким образом, необходимо будет использовать '   ВКЛАДКА  ' , куда Вы помещаете литеральную вкладку между кавычками. 

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' result <(sort -t \t', не будет заменен вкладкой, таким образом, необходимо будет использовать ' ВКЛАДКА ' , куда Вы помещаете литеральную вкладку между кавычками.

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' -k 1 "$f") > newresult

\t', не будет заменен вкладкой, таким образом, необходимо будет использовать ' ВКЛАДКА ' , куда Вы помещаете литеральную вкладку между кавычками.

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' result temp > newresult

могут быть заменены [1 115]

join -1 1 -2 1 -t  \t', не будет заменен вкладкой, таким образом, необходимо будет использовать '   ВКЛАДКА  ' , куда Вы помещаете литеральную вкладку между кавычками. 

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' result <(sort -t \t', не будет заменен вкладкой, таким образом, необходимо будет использовать ' ВКЛАДКА ' , куда Вы помещаете литеральную вкладку между кавычками.

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112] \t' -k 1 "$f") > newresult

\t', не будет заменен вкладкой, таким образом, необходимо будет использовать ' ВКЛАДКА ' , куда Вы помещаете литеральную вкладку между кавычками.

Оптимизация возможна, если, вместо /bin/sh, можно использовать современную оболочку, такую как удар или ksh; например, строки

[111]

могут быть заменены [1 115] [112]

0
ответ дан 29.09.2019, 18:50

Теги

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