Объединить несколько строк на основе первого столбца, но все столбцы должны оставаться отдельными

Это также может быть вызвано невозможностью привязки к порту на локальной стороне.

ssh -Nn -L 1234:remote:5678 user@remote

Эта команда пытается связать прослушиваемый порт 1234 на локальном компьютере, который сопоставляется со службой на порту 5678 на удаленном компьютере.

Если порт 1234 на локальном компьютере уже используется другим процессом, (возможно, фоновый ssh ​​-f сеанс ), тогда ssh не сможет прослушивать этот порт и туннель не будет работать..

Проблема в том, что это сообщение об ошибке может означать несколько вещей, а фраза «административно запрещена» иногда дает неверное представление. Таким образом, в дополнение к проверке DNS, брандмауэров между локальным и удаленным и конфигурации sshd _, проверьте, не используется ли уже локальный порт. Используйте

lsof -ti:1234

, чтобы выяснить, какой процесс запущен на 1234. Вам может понадобиться sudo, чтобы lsof вывел список процессов, принадлежащих другим пользователям. Затем вы можете использовать

ps aux | grep <pid>

, чтобы выяснить, что это за процесс.

Чтобы получить все это одной командой:

ps aux | grep "$(sudo lsof -ti:1234)"
2
29.04.2020, 04:25
2 ответа

Еще один awk.

Я задавался вопросом, не будет ли итерация по ассоциативному массиву for (f in fields)скремблировать вывод поля, но, проведя несколько тестов с шириной до 20 полей, похоже, что нет.

Предположим, что ваши заголовки находятся в строке 1, данные отсортированы (в соответствии с сообщением )и что у вас есть масса данных, которые вы не хотите хранить в памяти сразу

awk 'BEGIN{getline; split($0,out,"\t"); old=$1}
    old!=$1{for (o in out) printf "%s\t", out[o]; print""; delete out;old=$1}
    {split($0,tmp,"\t"); for (t in tmp) out[t]=(t==1)?tmp[t]:out[t]+tmp[t]}
    END{for (o in out) printf "%s\t", out[o];}' file

Этот вход

head    c1  c2  c3
H1  -0.71       
H1      2   
H1          3
H2  11  12  
H2          13

Дает

head    c1      c2      c3
H1      -0.71   2       3
H2      11      12      13

Прохождение

Возьмите первую строку и запомните первое поле вold

awk 'BEGIN{getline; split($0,out,"\t"); old=$1}

Если первое поле в следующей записи отличается от последнего (нового заголовка ), то последняя агрегация завершена, поэтому распечатайте ее, очистите массив агрегации outи отметьте, что вы находитесь в новый комплектold=$1

    old!=$1{for (o in out) printf "%s\t", out[o]; print""; delete out;old=$1}

Разделить $0на массив tmp, выполнить итерацию по массиву, добавив значение tmpк out, если только это не столбец заголовка, когда вы просто берете значение

    {split($0,tmp,"\t"); for (t in tmp) out[t]=(t==1)?tmp[t]:out[t]+tmp[t]}

Очистить последний набор записей, хранящихся в outвEND

    END{for (o in out) printf "%s\t", out[o];}' file
1
19.03.2021, 02:28

Вот так:

$ awk -F"\t" '{if(NR==1){ cols=NF; print; } else{for(i=2;i<=NF;i++){if(length($i)>0){data[$1][i]=$i}}}}END{for(id in data){ printf "%s",id; for(i=2;i<=cols;i++){printf "\t%s", data[id][i]} print ""}}' file 
OG  FC_AG_NICO  FC_AG_ZEA   FC_AG_BRAS  FC_MB_NICO  FC_MB_ZEA   FC_MB_BRAS  FC_TN_NICO  FC_TN_ZEA   FC_TN_BRAS  FC_SL_NICO  FC_SL_ZEA   FC_SL_BRAS  FC_SE_NICFC_SE_ZEA  FC_SE_BRAS 
OG0004400   -0.787302663    -0.710790578    0.663333543 -0.360799687    -0.0958126  0.056722264 -1.77626686 -0.971114297    0.707963822 -0.373838773    0.277055943 0.481626213 -1.659046364    -1.019969932
OG0004402   -0.304209641    -0.259080399    0.44366888  0.253000346 0.338511357 -0.121760564                -0.274550145    0.1933262   0.374095809 0.442748804 0.042958499

Или,немного легче читать:

awk -F"\t" '{
                ## Print the headers and store the number of columns.
                if(NR==1){ 
                    cols=NF;
                    print; 
                } 
                else{
                    ## Iterate over all columns, starting from the 2nd.
                    for(i=2;i<=NF;i++){
                        ## If this one isn't empty, store it.
                        if(length($i)>0){
                            data[$1][i]=$i
                        }
                    }
                }
            }
           ## After reading everything, print.
            END{
                for(id in data){ 
                    printf "%s",id; 
                    for(i=2;i<=cols;i++){
                        printf "\t%s", data[id][i]
                    } 
                    print ""
                }
            }' file 

Обратите внимание, что это предполагает, что каждый ID (1-е поле )имеет значение для каждого столбца в одной строке и только в одной строке. Если у вас могут быть пустые столбцы для идентификатора, вам понадобится немного другой подход.

2
19.03.2021, 02:28

Теги

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