Удалить столбцы с разделителями табуляции, соответствующие подстроке в первой строке

Вы не можете ссылаться на переменную awk внутри регулярного выражения /regex/.

Если вы хотите проверить наличие префикса POSIXly, используйте вместо этого функцию index():

FN="fileA_someprefix_20160101.txt" awk 'index(ENVIRON["FN"], $1) == 1' 

Из POSIX specs для awk:

index(s, t)

Возвращает позицию, в символах, нумерация от 1, в строке s, где впервые встречается строка t, или ноль, если она не встречается вообще.

0
27.05.2019, 15:52
2 ответа
awk -F '\t' -f script.awk file

где script.awkэто

BEGIN { OFS = FS }

FNR == 1 {
    for (i = 1; i <= NF; ++i)
        if ($i !~ /_HET/)
            keep[i] = 1
}

{
    nf = split($0, fields, FS)
    $0 = ""
    j = 0

    for (i = 1; i <= nf; ++i)
        if (i in keep)
            $(++j) = fields[i]

    print
}

Это сначала анализирует заголовки в первой строке и запоминает, какие из них мы хотим сохранить в ассоциативном массиве keep.

Затем для каждой строки он повторно -создает текущую запись (строку )только из тех полей, которые мы хотим сохранить, и распечатывает ее.

Это делается с помощью (re -)разделения строки текущего разделителя полей на массив fields, затем очистки всех полей (с помощью $0 = ""; это сбрасываетNF)и, наконец, назначает только поля из fields, которые являются ключами в массиве keep.

Некоторым нравится один -вкладыш:

awk -F '\t' -v OFS='\t' 'FNR==1{for(i=1;i<=NF;++i)if($i!~/_HET/)k[i]=1}{n=split($0,f,FS);$0=j="";for(i=1;i<=n;++i)if(i in k)$(++j)=f[i]}1' file

Я не полностью следовал вашему коду, но $i=="_HET"сравнит i:-е поле со строкой _HET. Этот тест завершится ошибкой, если значение поля не равно точно _HET(, а ни одно из ваших полей заголовка не равно ).


Совершенно другой подход:

cut -f "$( awk -F '\t' -v OFS="," '{for(i=1;i<=NF;++i)if($i!~/_HET/)k[i]=1;$0="";for(i in k)$(++j)=i;print;exit}' file )" file

Здесь используется программа awk

BEGIN { OFS = "," }

{
    for (i = 1; i <= NF; ++i)
        if ($i !~ /_HET/)
            keep[i] = 1

    $0 = ""

    for (i in keep)
        $(++j) = i

    print
    exit
}

не выводить содержимое требуемых столбцов, а выводить их номера столбцов в виде строки, -разделенной запятыми. Затем эта строка используется cutдля вырезания столбцов из данных.

2
28.01.2020, 02:30

Вы можете сделать это с помощью Perl, как показано:

$ perl -F'/\t/' -pale '$"="\t";
    $. == 1 and @A = grep { $F[$_] !~ /_HET/ } 0.. $#F;
    $_ = "@F[@A]";
' input.tsv
0
28.01.2020, 02:30

Теги

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