2015-06-06 2 views
1

Мне нужен скрипт awk для выбора столбцов из файла на основе списка столбцов в другом файле. Например:awk select columns из списка ввода

$cat cols 
3 2 6 4 

$cat text 
a b c d e f g 
h i j k l m n 

$awk_script cols text 
c b f d 
j i m k 

Таким образом, в этом порядке выбраны 3, 2, 6 и 4 столбцы.

Благодаря

ответ

2

Вы можете использовать это:

awk 'NR==FNR{n=split($0,c);next}{for(i=1;i<n;i++){printf "%s%s", $c[i], OFS};print ""}' cols text 

Мы передаем два входных файлов в AWK, сначала COLS затем текст. awk подсчитывает количество входных строк, обработанных во внутренней переменной NR. FNR - номер записи в текущем файле. При чтении первой (и единственной) строки colsNR и FNR имеют значение 1, что означает выполнение следующего блока.

{n=split($0,c);next} разбивает всю линию, которая хранится в $0 в массив c с использованием глобальных разделителей полей и сохраняет число столбцов для печати в n. Позднее мы будем использовать n в цикле for. next сообщает awk, чтобы остановить обработку текущей строки и прочитать следующую строку ввода.

Блок {for(i=1;i<=n+1;i++){printf "%s",$c[i],OFS};print ""} выполняется на всех остальных строках, так как он не имеет префикса с условием. Цикл for выполняет итерацию через cols и печатает соответствующие столбцы, разделенные разделителем выходных файлов OFS. Наконец, мы печатаем новую строку.

Выход:

c b f d 
j i m k 
+1

Никогда не делать Printf с входными данными в поле формата ('PRINTF $ C [я]'), используйте полный PRINTF синопсис вместо 'Printf "% s" , $ c [i] '. Представьте себе разницу, если '$ c [i]' содержит строку форматирования printf, например. '% S'. Вам не хватает печати OFS между полями. Для ясности и эффективности цикл должен заканчиваться на '<= n', а не'

+1

@EdMorton Спасибо за советы. Очень признателен! Я отредактировал его. Решение добавляет теперь и добавочную 'OFS' в конце каждой строки, но это должно быть достаточно хорошо, поскольку OFS является пространством. – hek2mgl

3
$ awk 'NR==FNR{n=split($0,f);next} {for (i=1;i<=n;i++) printf "%s%s", $(f[i]), (i<n?OFS:ORS)}' cols text 
c b f d 
j i m k