Эта часть вашего скрипта не имеет смысла:
{if (NR > 1) {print fn,fnr,nl}
fn=FILENAME; fnr = 1; nl = 0}
{fnr = FNR}
/ERROR/ && FILENAME ~ /\.gz$/ {nl++}
Позвольте мне перестроить его немного и прокомментировать его, чтобы он яснее, что он делает:
{ # for every line of every input file, do the following:
# If this is the 2nd or subsequent line, print the values of these variables:
if (NR > 1) {
print fn,fnr,nl
}
fn = FILENAME # set fn to FILENAME. Since this will occur for the first line of
# every file, this is that value fn will have when printed above,
# so why not just get rid of fn and print FILENAME?
fnr = 1 # set fnr to 1. This is immediately over-written below by
# setting it to FNR so this is pointless.
nl = 0
}
{ # for every line of every input file, also do the following
# (note the unnecessary "}" then "{" above):
fnr = FNR # set fnr to FNR. Since this will occur for the first line of
# every file, this is that value fnr will have when printed above,
# so why not just get rid of fnr and print FNR-1?
}
/ERROR/ && FILENAME ~ /\.gz$/ {
nl++ # increment the value of nl. Since nl is always set to zero above,
# this will only ever set it to 1, so why not just set it to 1?
# I suspect the real intent is to NOT set it to zero above.
}
Вы также код выше тестирования для имени файла, которое заканчивается на «.gz», но затем вы запускаете gunzip для каждого файла в следующем блоке.
Помимо этого, просто вызовите gunzip из оболочки, как и все остальные. awk - инструмент для синтаксического анализа текста, это не среда, из которой можно вызвать другие инструменты - вот для чего предназначена оболочка.
Например, предполагается, что ваш комментарий (prints the file name, number of lines in each file and number of lines found containing 'ERROR
) точно описывает то, что вы хотите, чтобы ваш скрипт AWK делать и предполагая, что это имеет смысл проверить слово «ERROR» непосредственно в «.gz» файл, используя AWK:
for file in /tmp/appscraps/*.gz
do
awk -v OFS=',' '/ERROR/{nl++} END{print FILENAME, NR+0, nl+0}' "$file"
gunzip -cd "$file"
done > /tmp/test.txt
Гораздо понятнее и проще, не так ли?
Если это не имеет смысла, чтобы проверить для слова ERROR непосредственно в файле «.gz», то вы можете сделать это вместо:
for file in /tmp/appscraps/*.gz
do
zcat "$file" | awk -v file="$file" -v OFS=',' '/ERROR/{nl++} END{print file, NR+0, nl+0}'
gunzip -cd "$file"
done > /tmp/test.txt
Для обработки GZ и не GZ файлы, как вы «в в настоящее время описано в своем комментарии ниже:
for file in /tmp/appscraps/*
do
case $file in
*.gz) cmd="zcat" ;;
*) cmd="cat" ;;
esac
"$cmd" "$file" |
awk -v file="$file" -v OFS=',' '/ERROR/{nl++} END{print file, NR+0, nl+0}'
done > /tmp/test.txt
Я ушел из Gunzip, так как вам не нужно это, насколько я могу сказать от ваших заявленных требований. Если я ошибаюсь, объясните, для чего вам это нужно.
Термин «обычный файл» имеет техническое значение, а файл «gzip» является обычным файлом. Вы имеете в виду «текстовый файл». –