У меня есть следующий файл:
id name age
1 ed 50
2 joe 70
Я хочу напечатать только id
и age
столбцы. Прямо сейчас я просто использую awk
:
cat file.tsv | awk '{ print $1, $3 }'
Однако для этого необходимо знать номера столбцов. Есть ли способ сделать это, где я могу использовать имя столбца (указано в первой строке), а не номер столбца?
cat
не обязательно, кстати. Вы могли бы использоватьawk '{ print $1, $3 }' file.tsv
id
вместо$1
иage
вместо$3
Ответы:
Может быть, что-то вроде этого:
Если вы хотите указать столбцы для печати в командной строке, вы можете сделать что-то вроде этого:
(Обратите внимание на
-v
переключатель, чтобы получить переменную, определенную вBEGIN
блоке.)источник
awk -f t.awk col1 col2 ... coln input
было бы идеально;awk -f t.awk cols=col1,col2,...,coln input
будет работать тожеfor (i in out)
не имеет внутреннего порядка.gawk
предлагаетPROCINFO["sorted_in"]
в качестве решения, итерации по индексу с,for( ; ; )
вероятно, лучше.Просто добавим Perl-решение в пакет:
источник
csvkit
Преобразуйте входные данные в формат CSV и используйте инструмент CSV, например
csvcut
изcsvkit
:Установите csvkit:
Используйте
tr
его с параметром squeeze,-s
чтобы преобразовать его в действительный файл CSV и применитеcsvcut
:Если вы хотите вернуться к старому формату данных, вы можете использовать
tr ',' ' ' | column -t
Заметки
csvkit также поддерживает разные разделители ( общая опция
-d
или--delimiter
), но возвращает файл csv:Если файл использует только пробелы для разделения столбцов (без вкладок вообще), следующие работы
Если файл использует вкладку для разделения столбцов, следующие действия и
csvformat
могут быть использованы для возврата файла TSV:Насколько я проверил, допускается только одна вкладка.
csvlook
можно отформатировать таблицу в формате уценкиUUOC (Бесполезное использование кошки) : мне нравится этот способ создания команды.
источник
tr
тоже. Файлы TSV поддерживаются напрямую, без необходимости конвертировать их в CSV. Опция-t
(aka--tabs
) говоритcvscut
использовать вкладки в качестве разделителя полей. И-d
или--delimiter
использовать любой символ в качестве разделителя.-d
и-t
варианты пола разбитым. они работают для указания входного разделителя, но выходной разделитель жестко закодирован, чтобы всегда быть запятой. IMO не работает - он должен быть таким же, как входной разделитель, или иметь другую опцию, позволяющую пользователю установить выходной разделитель, напримерawk
, FS и OFS.Если вы просто хотите ссылаться на эти поля по именам, а не по номерам, вы можете использоватьread
:РЕДАКТИРОВАТЬ
Наконец-то я понял твой смысл! Вот функция bash, которая распечатывает только те столбцы, которые вы указали в командной строке (по имени ).
Вот как вы можете использовать его с файлом, который вы представили:
(Функция читает
stdin
.< file.tsv printColumns ...
ЭквивалентноprintColumns ... < file.tsv
иcat file.tsv | printColumns ...
)Примечание: обратите внимание на названия столбцов, которые вы запрашиваете! В этой версии отсутствуют проверки работоспособности, поэтому могут произойти неприятные вещи, если один из аргументов
"anything; rm /my/precious/file"
источник
id
,name
иage
, не меняет тот факт , что порядок жестко закодирован в вашейread
линии.time { command(s); }
).time cat temp.txt | ./col1 CHR POS > /dev/null 99.144u 38.966s 2:19.27 99.1% 0+0k 0+0io 0pf+0w time awk -f col2 c1=CHR c2=POS temp.txt > /dev/null 0.294u 0.127s 0:00.50 82.0% 0+0k 0+0io 0pf+0w
Для чего это стоит. Это может обрабатывать любое количество столбцов в источнике и любое количество столбцов для печати в любой выходной последовательности, которую вы выберете; просто переставить арги ...
например. вызов:
script-name id age
выход
источник
Если файл, который вы читаете, никогда не может быть сгенерирован пользователем, вы можете использовать встроенную функцию чтения:
Вся первая строка входного файла подставляется в список аргументов, поэтому
read
все имена полей из строки заголовка передаются как имена переменных. Первому из них присваивается 1, которыйseq 100
генерирует, второму - 2, третьему - 3 и так далее. Избыточныйseq
вывод поглощается фиктивной переменнойextra
. Если вы знаете количество входных столбцов заблаговременно, вы можете изменить 100, чтобы соответствовать и избавиться отextra
.awk
Сценарий представляет собой двойные кавычки, позволяя переменные оболочки , определенныйread
быть замещены в сценарий в качествеawk
номера поля.источник
Обычно проще взглянуть на заголовок файла, сосчитать номер нужного вам столбца ( c ) и затем использовать Unix
cut
:Но когда есть много столбцов или много файлов, я использую следующую уродливую уловку:
Протестировано на OSX,
file.csv
разделено запятыми.источник
Вот один быстрый способ выбора одного столбца.
Скажем, мы хотим столбец с именем "foo":
В основном, возьмите строку заголовка, разделите ее на несколько строк с одним именем столбца на строку, пронумеруйте строки, выберите строку с нужным именем и получите соответствующий номер строки; затем используйте этот номер строки в качестве номера столбца для команды вырезания.
источник
Ища подобное решение (мне нужен столбец с именем id, который может иметь различный номер столбца), я наткнулся на это:
источник
Я написал скрипт Python для этой цели, который в основном работает так:
Я назвал его
hgrep
для заголовка grep , его можно использовать так:Весь скрипт немного длиннее, потому что он использует
argparse
для разбора аргументов командной строки и код выглядит следующим образом:источник
awk
при всей своей винтажности, по сути, имеет целочисленный индекс, как естьcut
.Вот несколько инструментов, разработанных для обработки именованных данных (большинство из них обрабатывают только CSV и TSV, которые являются очень популярными форматами файлов):
источник
Попробуйте эту маленькую утилиту awk, чтобы вырезать определенные заголовки - https://github.com/rohitprajapati/toyeca-cutter
Пример использования -
источник