2012-05-21 4 views
2

Например, предположим, что я выполнить следующую команду:Возможно ли иметь другое поведение для первого и второго входных файлов для awk?

gawk -f AppendMapping.awk Reference.tsv TrueInput.tsv 

Пусть имена файлов изменится. Итерируя первый файл, я хочу создать сопоставление.

map[$16]=$18 

Итерируя второй файл, я хочу использовать отображение.

print $1, map[$2] 

Каков наилучший способ достижения этого поведения (то есть, различное поведение для каждого входного файла)?

ответ

4

Как вы, вероятно, знаете, NR хранит текущий номер строки; как вы можете или не можете знать, это кумулятивно - он не получает сброс между файлами. FNR, с другой стороны, специфичен для файла, поэтому вы можете использовать эти два, чтобы увидеть, находитесь ли вы в первом файле (за пределами второго вам нужно будет сохранить свой счетчик).

# In case you want to keep track of the file number 
FNR == 1 { fileno++ }*emphasized text* 

NR == FNR { 
    # First file 
} 
NR != FNR { 
    # Second or later file 
} 

Вы также можете использовать getline в BEGIN блоке в цикле через него вручную.

BEGIN { 
    file = ARGV[1] 
    while(getline < file) { 
     # Process line 
    } 
    delete ARGV[1] 
} 
+1

Часто цикл 'NR == FNR' имеет' next' в качестве последнего оператора. Когда это используется, нет необходимости в «NR! = FNR», и другие условия выбора более упрощаются. –

1

версии поглазеть 4 и высокое предложение специального BEGINFILEENDFILE) блок, а также обычные BEGIN и END блок. Используйте их для установки флагов, по которым вы меняете поведение вашего кода.

Напомним, что patterns can include comparisons with variables, так что вы можете выбрать паттерны непосредственно по значению ваших флагов.

Страница человек говорит:

Для каждого входного файла, если правило BEGINFILE существует, простак выполняет соответствующий код перед обработкой содержимое файла. Аналогично, gawk выполняет код, связанный с ENDFILE, после обработки файла .

+0

Это доступно только с GAWK 4. –

+0

@DennisWilliamson Спасибо. Ограничения версии добавлены в текст. – dmckee

0

Это может работать для вас:

seq 5 >/tmp/a 
seq 100 105 >/tmp/b 
awk 'FILENAME==ARGV[1]{print FILENAME,$0};FILENAME==ARGV[2]{print $0,FILENAME}' /tmp/{a,b} 
/tmp/a 1 
/tmp/a 2 
/tmp/a 3 
/tmp/a 4 
/tmp/a 5 
100 /tmp/b 
101 /tmp/b 
102 /tmp/b 
103 /tmp/b 
104 /tmp/b 
105 /tmp/b 

Итак, комбинируя FILENAME с ARGV[n] где n является п-й файл в командной строке, awk условно можно изменить отдельные файлы.

N.B. ARGV [0] будет командой awk.

 Смежные вопросы

  • Нет связанных вопросов^_^