Извлеките начальную и конечную позиции общего идентификатора

У вас неправильная раскладка клавиатуры, что означает, что клавиатура неправильно сопоставлена ​​с символами, отличными от тех, которые изображены на клавишах.

Чтобы изменить раскладку в KDE, запустите KRunner, используя правильную комбинацию клавиш (по умолчанию Alt + Пробел ), введите клавиатура и откройте клавиатуру. настройки. Перейдите в раздел «Макеты», убедитесь, что установлен флажок «Настроить макеты», и убедитесь, что текущая раскладка клавиатуры соответствует вашей текущей клавиатуре. Если это не так, замените его на подходящий.

Keyboard layout settings

6
19.01.2017, 11:31
5 ответов

С GNU кэш данных :

datamash -H -W -g 1,2 min 3 max 4 <input
6
27.01.2020, 20:23

Другое решение с awk и хранением в переменных:

Возьмите заголовки файла и поместите их в выходной файл:

row1=$(head -1 input_file)
echo $row1 | sed -e 's/ /\t/g' > output_file

Возьмите уникальные значения первого столбца:

col1=$(for i in $(awk 'NR>1 {print $1}' input_file | uniq); do echo $i; done)

Возьмите первое вхождение значения во второй строке на основе каждого значения первого столбца:

col2=$(for i in $(echo "$col1"); do grep -m1 $i input_file | awk '{print $2}'; done)

Возьмите первое значение третьего столбца на основе каждого значения первого столбца:

col3=$(for i in $(echo "$col1"); do grep -m1 $i input_file | tail -1 | awk '{print $3}'; done)

Возьмите последнее значение четвертого столбца на основе каждого значения первого столбца:

col4=$(for i in $(echo "$col1"); do grep $i input_file | tail -1 | awk '{print $4}'; done)

Добавьте все эти значения в выходной файл:

paste -d'\t' <(echo "$col1") <(echo "$col2") <(echo "$col3") <(echo "$col4") >> output_file
0
27.01.2020, 20:23

Предполагая, что записи для каждого идентификатора отсортированы численно по начальной координате:

#!/usr/bin/awk -f

NR == 1  {
    # Deal with header (just print it and continue).
    print; 
    next;
}

$1 != id {
    # This is a new ID.
    # Display the data for the ID we've been processing so far (if any).
    if (id) {
        print id, chr, start, stop;
    }

    # Store the data for the new ID.
    id      = $1;
    chr     = $2;
    start   = $3;
}

{
    # The stop/end coordinate will be updated for each line.
    stop = $4;
}

END {
    # At the end, display the data for the last ID.
    print id, chr, start, stop;
}

Тестирование (работает с GNU awk , BSD awk и mawk ):

$ ./script.awk data.in
Id       Chr     Start   End
Prom_1 chr1 3978952 3979193
Prom_2 chr1 4379047 4379622
Prom_3 chr1 5184469 5184496

Если записи не отсортированы, отсортируйте их:

$ sort -k1,1 -k3,3n -o data.in data.in

Это может испортить строку заголовка. Вот альтернативный вариант, который будет работать:

$ cat <( head -n 1 data.in ) <( sed '1d' data.in | sort -k1,1 -k3,3n ) >data.new
$ mv data.new data.in

Требуется bash или ksh , хотя ...

1
27.01.2020, 20:23

Это можно сделать с помощью классического цикла для чтения файла или другими способами, например с awk, но я плохо разбираюсь в awk, чтобы дать вам решение, основанное на awk. Решение Bellow работает нормально в bash и использует простые awk, grep и массивы.

С известным идентификатором (параметром или вводом пользователя)

id="Prom_1" #Or for user input read -p "Give Id :" id
header=$(head -1 a.txt) #get the 1st line and store it as header.
data=($(grep $id a.txt)) #grep the file for given the id and fill an array
echo "$header"
echo -e "${data[0]}\t${data[1]}\t${data[2]}\t${data[-1]}" #data[-1] refers to the last element of the data array
#Output:
Id       Chr     Start   End  
Prom_1  chr1    3978952 3979193

Хитрость заключается в том, что массив получает все значения grep, разделенные пробелом (IFS по умолчанию), и поэтому массив выглядит следующим образом:

root@debi64:# id="Prom_1";data=($(grep $id a.txt));declare -p data
declare -a data=([0]="Prom_1" [1]="chr1" [2]="3978952" [3]="3978953" [4]=$'\nProm_1' [5]="chr1" [6]="3979165" [7]="3979166" [8]=$'\nProm_1' [9]="chr1" [10]="3979192" [11]="3979193")
#declare -p command just prints out all the data of the array (keys and values)

Чтобы автоматически просканируйте файл на предмет идентификаторов, вы можете использовать программу uniq следующим образом:

readarray -t ids< <(awk -F" " '{print $1}' a.txt |uniq |tail -n+2) 
#For Field separator= " " print the first field (id), print them as unique fields and store them in an array.
#Here the use of readarray is better to handle data separated by new lines.
declare -p ids
#Output: declare -a ids=([0]="Prom_1" [1]="Prom_2" [2]="Prom_3")

Объединение всего вместе:

header=$(head -1 a.txt) #get the 1st line and store it as header.
readarray -t ids< <(awk -F" " '{print $1}' a.txt |uniq |tail -n+2)
echo "$header"
for id in ${ids[@]}
do
data=($(grep $id a.txt))
echo -e "${data[0]}\t${data[1]}\t${data[2]}\t${data[-1]}"
done 

#Output 
Id       Chr     Start   End  
Prom_1  chr1    3978952 3979193
Prom_2  chr1    4379047 4379622
Prom_3  chr1    5184469 5184496
2
27.01.2020, 20:23

вы можете попробовать эту awk

$ awk 'NR==1{print; next}NR!=1{if(!($1 in Arr)){printf("\t%s\n%s\t%s\t%s",a,$1,$2,$3);Arr[$1]++}else{a=$NF}}END{printf("\t%s\n",a)}' input.txt
Id       Chr     Start   End

Prom_1  chr1    3978952 3979193
Prom_2  chr1    4379047 4379622
Prom_3  chr1    5184469 5184496

awk '
NR==1{print; next}
NR!=1{
if(!($1 in Arr))
{
       printf("\t%s\n%s\t%s\t%s",a,$1,$2,$3);Arr[$1]++;
}
else
{
    a=$NF
}
}
END{
printf("\t%s\n",a)
}' input.txt
2
27.01.2020, 20:23

Теги

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