Unix - Отпечатайте общи редове един до друг

Искам да сравня 2 несортирани файла и да отпечатам общите редове един до друг

Файл1

a 1 2
b 2 4
c 1 4
e 1 2

Файл2
a 0 3
c 1 4
d 3 4
b 2 4

изход1

a 1 2 0 3
b 2 4 2 4
c 1 4 1 4

изход2
a 1 2 0 3
b 2 4 2 4
c 1 4 1 4
d 3 4
e 1 2

Мога да постигна с помощта на Join, но искам да намеря команда с помощта на awk.

Можем ли да го направим, без да сортираме файла и да използваме awk, за да получим output1 и output2?


person Aparna    schedule 31.05.2016    source източник


Отговори (2)


$ awk '
    NR==FNR {line[$1]=$0; next} 
    $1 in line {
        f2fields = gensub($1 FS, "", 1)
        print line[$1], f2fields > "output1"
        print line[$1], f2fields > "output2"
        seen[$1]++
        next
    } 
    {print > "output2"} 
    END { for (key in line) if (!(key in seen)) print line[key] > "output2" }
' file1 file2

$ cat output1
a 1 2 0 3
c 1 4 1 4
b 2 4 2 4

$ cat output2
a 1 2 0 3
c 1 4 1 4
d 3 4
b 2 4 2 4
e 1 2

Редът на изходните {1,2} файлове се определя от 1) реда на записите на file2, след това 2) записите на file1, които не се появяват във file2, се извеждат "на случаен принцип" (в хеш ред).

person glenn jackman    schedule 31.05.2016
comment
Благодаря ви за отговора. Опитах командата, но тя не работи за мен. Модифицирах f2fileds и опитах за output1, но вторият файл се отпечатва с ключовата колона. Можете ли да посъветвате как да извлека втория файл само от втората колона? awk -F , 'FNR==NR{a[$1]=$0;следващ} $1 в a{f2=$0; print a[$1],f2;next} ' file1 file2 › output1 $ cat output1 a 1 2 a 0 3 c 1 4 c 1 4 b 2 4 b 2 4 - person Aparna; 01.06.2016

Можете да го направите с GNU awk по следния начин:

script.awk

BEGIN { PROCINFO["sorted_in"] = "@ind_str_asc" }

FNR == NR { lines[$1] = $0; next }
FNR != NR { if( $1 in lines ) {
              k = $1
              # strip unnecessary key $1 from $0
              $1 = ""
              lines[ k ] = lines[ k ] $0
            }
            else lines[$1] = $0;
          }

END { for( k in lines ) print lines[ k ] }

използвайте го така: awk -f script.awk file1 file2

Нещото PROCINFO е специално за gnu awk. Ако не се нуждаете от сортиране и нямате gnu awk, можете да коментирате първия ред и да видите какво ще се случи.

person Lars Fischer    schedule 31.05.2016
comment
Благодаря ви за отговора. Опитах командата, но тя не работи за мен. Модифицирах f2fileds и опитах за output1, но вторият файл се отпечатва с ключовата колона. Можете ли да посъветвате как да извлека втория файл само от втората колона? awk -F , 'FNR==NR{a[$1]=$0;следващ} $1 в a{f2=$0; print a[$1],f2;next} ' file1 file2 › output1 $ cat output1 a 1 2 a 0 3 c 1 4 c 1 4 b 2 4 b 2 4 - person Aparna; 01.06.2016
comment
@Apama премахването на ключа за файл две се извършва в действието FNR != NR чрез задаване на $1= "" и след това използване на $0. Поне в GNU awk $0 се актуализира и след това се състои от оригиналния $2 ... $5. Ако това не работи, използвайте: lines[ k ] = lines[ k ] $2 $3 $4 $5 вместо това. Между другото, получавате output1, като коментирате else частта. - person Lars Fischer; 01.06.2016
comment
@Apama в първия си коментар използвате „awk -F“, което предполага разделител на полето със запетая. Примерите във въпроса са разделени с интервал, така че не съм сигурен дали имате нужда от частта -F "," или не. - person Lars Fischer; 01.06.2016
comment
Благодаря ти много. Това беше правописна грешка поради различните тествани файлове. Въпреки това FS dint причинява проблема за мен. Успях да разреша проблема с печатането от $2. - person Aparna; 02.06.2016