
У меня есть файл с 500 столбцами. Мне нужно удалить некоторые столбцы, названия которых описаны в списке в другом файле. Например
fileA
:
id1 id22 id43 id4 id5 id6 id7 id68 id9 id10 id11
TT AA AG TC TT AA AG TC DD AA CC
TT AC GG TC TT AG AG TC AD AA DC
fileB
:
id1
id5
id10
id68
Желаемый результат:
id22 id43 id4 id6 id7 id9 id11
AA AG TC AA AG DD CC
AC GG TC AG AG AD DC
решение1
Не знаю, можно ли назвать это однострочным заданием, но это можно сделать на лету с помощью самых простых инструментов:
cut -d' ' -f $(head -n 1 fileA | tr -s ' ' '\n' | cat -n | grep -wvf fileB | cut -f 1 | tr '\n ' ',' | sed -e 's/,$//' -e 's/^,//') fileA
Объяснение:
Команда просто использует пробел в качестве разделителя и выбирает, какие поля оставить. Затем возникает вопрос, какие поля/столбцы использовать, которые задаются списком индексов, разделенных запятыми, который мы создаем на лету cut
:cut -d' ' -f [...] fileA
-d' '
-f
head -n 1 fileA
выбирает только строку заголовка, tr -s ' ' '\n'
заменяет все пробелы на новые строки (и -s
объединяет несколько вхождений в одно), cat -n
добавляет номера строк в этот список.
Эти номера строк идентичны исходным номерам столбцов, поэтому нам нужно выбрать оставшиеся. С помощью grep -wvf fileB
мы делаем обратный grep
пинг с заголовками из списка удаления (используйте , -w
чтобы убедиться, что eg id1
также не удаляет id11
), затем cut -f 1
этот список только для номеров строк и преобразуем новые строки в запятые ( tr '\n' ','
), что дает нам наш разделенный запятыми список оставшихся столбцов. Однако на последнем шаге все еще есть запятые до и после списка, поэтому нам нужно удалить их с помощью sed -e 's/,$//' -e 's/^,//'
. Итак, теперь cut
список полей внешнего ' завершен.
Возможно, сначала следует запустить внутренние трубы отдельно в качестве встречной проверки — избыточный индекс столбца не повлияет на результат.