Сравнение двух файлов с разделителями табуляции на основе первого столбца обоих файлов и печати совпадающих и несовпадающих записей в выходном файле

Да, программы вполне могут использовать оболочку явно или неявно.

См., например,. Ответ Стефана на несвязанный вопрос.

Их ответ говорит, например, что если программа использует библиотечные функции C execlp()или execvp()для запуска команды, после execve()возврата ENOEXECона обычно вызывает shдля нее (. ] "it" является сценарием оболочки без явного указания интерпретатора, который является контекстом для этого вопроса ). sh— оболочка.

Приложение, использующее system()для выполнения утилиты, также обычно вызывает оболочку.

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

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

3
12.09.2020, 14:54
5 ответов

Сначала прочитайте fileB.txt, сделайте 1-е поле ключом, а 2-е поле — его значением в массиве, пропуская строку заголовка сFNR>1(Что такое NR и FNR и что означает «NR==FNR»?).

Затем прочитайте fileA.txt, напечатайте его заголовок для первой строки, а затем напечатайте его 1-е поле, за которым следует соответствующий элемент в массив, если есть.

awk '
    FNR==NR && FNR>1{a[$1]=$2}
    NR!=FNR{
        if(FNR>1){print $1,a[$1]}
        else{print "id", "freq.var"}
    }
' OFS="\t" fileB.txt fileA.txt

OFS="\t"устанавливает разделитель полей вывода на табуляцию. Поскольку ваш файл разделен табуляцией, я предполагаю, что выходной файл также должен быть разделен табуляцией.

Вы можете передать это в column -tдля выравнивания.

5
18.03.2021, 23:05

Как насчет того, чтобы не использовать основы bash, а использовать что-то более удобное, например SQL (, поддерживаемое таким инструментом, как q)?

q -H -O -t 'SELECT id, `freq.var` FROM fileA.txt as a LEFT OUTER JOIN fileB.txt as b ON a.id = b.chr_pos'
1
18.03.2021, 23:05

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

$ join -a1 -j1 -t$'\t' <(tail -n+2 fileA.txt | sort)  <(tail -n+2 fileB.txt | sort)
chr1_45796849_A_T   0.028399811
chr1_45796852_G_C   0.019154034
chr1_45796854_C_T   0.015872901
chr1_45797153_A_T   0.010129176
chr1_45797174_T_A
chr1_45797487_A_G   0.012981216
chr1_45797750_C_T   0.024949931
chr19_9002576_T_C
chr19_9018540_A_G

Или, чтобы сохранить заголовки:

$ ( printf 'id\tfreq.var\n'; join -t$'\t' -a1 -j1 <(tail -n+2 fileA.txt | sort)  <(tail -n+2 fileB.txt | sort))
id  freq.var
chr1_45796849_A_T   0.028399811
chr1_45796852_G_C   0.019154034
chr1_45796854_C_T   0.015872901
chr1_45797153_A_T   0.010129176
chr1_45797174_T_A
chr1_45797487_A_G   0.012981216
chr1_45797750_C_T   0.024949931
chr19_9002576_T_C
chr19_9018540_A_G

И красиво -печатать:

$ ( printf '%-20s\t%s\n' "id" "freq_var"; join -t$'\t' -a1 -j1 <(tail -n+2 fileA.txt | sort)  <(tail -n+2 fileB.txt | sort))
id                      freq_var
chr1_45796849_A_T   0.028399811
chr1_45796852_G_C   0.019154034
chr1_45796854_C_T   0.015872901
chr1_45797153_A_T   0.010129176
chr1_45797174_T_A
chr1_45797487_A_G   0.012981216
chr1_45797750_C_T   0.024949931
chr19_9002576_T_C
chr19_9018540_A_G
4
18.03.2021, 23:05
$ cat tst.awk
BEGIN { FS=OFS="\t" }
NR==FNR {
    map[(NR>1 ? $1 : "id")] = $2
    next
}
{ print $1, map[$1] }
$ awk -f tst.awk fileB fileA
id  freq.var
chr1_45796849_A_T   0.028399811
chr1_45796854_C_T   0.015872901
chr1_45797174_T_A
chr1_45796852_G_C   0.019154034
chr19_9018540_A_G
chr19_9002576_T_C
chr1_45797487_A_G   0.012981216
chr1_45797153_A_T   0.010129176
chr1_45797750_C_T   0.024949931
3
18.03.2021, 23:05

GNU sed с включенным режимом расширенных регулярных выражений -Eи без автопечати -n. Сначала прочитайте файл B и сохраните его в резервном пространстве. Затем для каждой строки файла A сравните, найдена ли она в удержании.

sed -En '
  1{
    s/^\S+/id/
    :filea
      H;n
    /\t/b filea
    x;s/$/\n/;x
  }
  G
  s/^([^\n]+)\n.*\n(\1\t[^\n]*)\n.*/\2/p;t
  s/\n.*/\t/p
' fileB.txt fileA.txt

Результат:

id  freq.var
chr1_45796849_A_T   0.028399811
chr1_45796854_C_T   0.015872901
chr1_45797174_T_A   
chr1_45796852_G_C   0.019154034
chr19_9018540_A_G   
chr19_9002576_T_C   
chr1_45797487_A_G   0.012981216
chr1_45797153_A_T   0.010129176
chr1_45797750_C_T   0.024949931
0
18.03.2021, 23:05

Теги

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