2015-10-18 5 views
1

Я новичок awk и, по общему признанию, не понимаю, как FNR NR подключается к файлам. Я могу получить два входных файла. Мне нужно добавить еще один (inputFile3).Несколько входных файлов awk command line

Я бегу из командной строки:

awk -f parseField.awk inputFile1.csv inputFile2.csv ./inputFile3.TXT 

В настоящее время, я петля через inputFile3 с помощью:

FNR!=NR {...} 

I проходное inputFile1 с помощью:

FNR==NR {...} 

мне нужно для добавления другого файла в микс (inputFile2). Каков синтаксис, который я могу использовать в своем awk-скрипте (parseField) для доступа к этому третьему входному файлу?

+2

'FNR' ==«Входной номер записи в текущем входном файле «. 'NR' ==" Общее количество входных записей, зарегистрированных до сих пор. " поэтому 'FNR == NR' для первого файла и отличается для каждого другого файла. Что вы пытаетесь сделать со своим третьим файлом? –

ответ

4

Чтобы добавить к хорошей информации @EtanReisner, вы можете оставить свой счетчик: FNR==1 {file_number++}. Это увеличит счетчик всякий раз, когда будет прочитана первая строка файла.

Все вместе, вы можете сказать:

#!/bin/awk -f 

BEGIN {print "start program"} 
NR==1 {print "reading first file"} 
FNR==1 {filenum++; print "I am in file number", filenum} 
{ ... } 

Если вы в GNU POSIX awk (thanks Jonathan Leffler) вы также можете использовать переменную FILENAME. Или также переменные ARGC и массив ARGV.


Также смотрите информацию об этом в Idiomatic awk:

Другая конструкция, которая часто используется в AWK выглядит следующим образом:

$ awk 'NR == FNR { # some actions; next} # other condition {# other actions}' file1.txt file2.txt 

Используется при обработке двух файлов. При обработке более одного файла awk считывает каждый файл последовательно, один за другим, в порядке , который указан в командной строке. Специальная переменная NR хранит общее количество записей ввода, прочитанных до сих пор, независимо от , сколько файлов было прочитано. Значение NR начинается с 1 и всегда увеличивается до тех пор, пока программа не завершится. Другая переменная, FNR, хранит количество записей, считанных из текущего обрабатываемого файла. Значение FNR начинается с 1, увеличивается до тех пор, пока не будет достигнут конец текущего файла , а затем снова будет установлен на 1, как только будет прочитана первая строка следующего файла и так далее. Итак, условие NR == FNR верно только , в то время как awk читает первый файл.

+0

FILENAME является частью POSIX ['awk'] (http://pubs.opengroup.org/onlinepubs/9699919799/utilities/awk.html). Так же, как и массив ARGV, и переменная ARGC - индексы ARGV начинаются с 0 (а не 1), а записанные аргументы исключают опции для awk и программы. –

+0

@JonathanLeffler да, поэтому я предлагаю использовать счетчик, когда 'FNR == 1' является самым надежным способом сделать это. – fedorqui

+1

Я согласен, что 'FNR == 1' является хорошим способом обнаружения изменения файла. Ваш комментарий о GNU Awk более ограничительный, чем нужно ('FILENAME' не только в GNU Awk). И знать, что ARGC и ARGV существуют, могут быть полезны. –

0

Не так элегантно, как решение POSIX FILENAME, но и полезно для пыльных, старых awk, которые не имеют слишком много функций. Вы можете сделать составную инструкцию, которая манипулирует данные перед отправкой awk в несколько способов ...

Вариант 1

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

file1

Line 1 of 1 

file2

Line 1 of 2 
Line 2 of 2 

file3

Line 1 of 3 
Line 2 of 3 
Line 3 of 3 

Вы можете сделать это:

{ echo 1; cat file1; echo 2; cat file2; echo 3; cat file3; } 
1 
Line 1 of 1 
2 
Line 1 of 2 
Line 2 of 2 
3 
Line 1 of 3 
Line 2 of 3 
Line 3 of 3 

и трубу, в awk и затем подобрать Номер_файла каждый раз, когда число полей 1

{ echo 1; cat file1; echo 2; cat file2; echo 3; cat file3; } | awk 'NF==1{file=$1;next} {print file,$0}' 
1 Line 1 of 1 
2 Line 1 of 2 
2 Line 2 of 2 
3 Line 1 of 3 
3 Line 2 of 3 
3 Line 3 of 3 

Вариант 2

Или вы может редактировать номер файла на начало или конец каждой строки, поэтому он доступен как $1 внутри awk, например:

{ sed 's/^/1 /' file1; sed 's/^/2 /' file2; sed 's/^/3 /' file3; } 
1 Line 1 of 1 
2 Line 1 of 2 
2 Line 2 of 2 
3 Line 1 of 3 
3 Line 2 of 3 
3 Line 3 of 3 

Итак, теперь вы можете сделать

{ sed 's/^/1 /' file1; sed 's/^/2 /' file2; sed 's/^/3 /' file3; } | awk '{file=$1; ...}' 

Я до сих пор голосуют за @ fedorqui решение которого, хотя :-)