AWK 中打开的文件太多
Too many open files in AWK
我遇到了一个问题,希望有人能帮助我。
我需要读取一个 gzip 压缩的大日志文件,对于读取的每一行,获取特定字段并根据该字段的值创建或将整行附加到该文件(gzip 压缩)。
最初我没有创建行或将行附加到 gzip 文件,但服务器上确实没有足够的 space,所以,我需要这样做。
由于在 AWK 中使用 gzip,使用管道和引号,结束部分(关闭文件)停止工作。
我试图将此关闭文件移动到 AWK 的开头,但我一直收到此消息(打开的文件太多消息。
在中间使用 gzip 之前,AWK 一切正常。
有效但不附加到 gzip 文件:
for _csv in $( ls ${_in_path}${_letter}_*_*.csv.gz ); do
zcat $_csv | sort -t',' -T tmp -k4 | awk -F "," '{ _key = ; _fn = "requests_by_IP/"_key".csv"; printf "%s\n", [=10=] >> _fn; close(_fn)}'
done
无效:
for _csv in $( ls ${_in_path}${_letter}_*_*.csv.gz ); do
zcat $_csv | sort -t',' -T tmp -k4 | awk -F "," '{ if (!_fn) { close(_fn); } _key = ; _fn = "requests_by_IP/"_key".csv.gz"; printf "%s\n", [=11=] | "gzip >> "_fn;}'
done
for _csv in $( ls ${_in_path}${_letter}_*_*.csv.gz ); do
zcat $_csv | sort -t',' -T tmp -k4 | awk -F "," ' _key = ; _fn = "requests_by_IP/"_key".csv.gz"; printf "%s\n", [=12=] | "gzip >> "_fn; close(_fn);}'
done
注意:如果我不在引号内使用 gzip 命令 ("gzip >> "),我会在 > error[=14= 处或附近收到此通用 语法错误]
编辑:非常感谢@edmorton!特别是 https://www.shellcheck.net/ 提示 !!!
awk 的输出是 "gzip >> "_fn
的管道,而不是名称存储在 _fn
中的文件,因此 that 是您需要的关闭,例如close("gzip >> "_fn)
。您应该 copy/paste 您的 shell 脚本到 http://shellcheck.net 并修复它首先告诉您的问题,因为您在 awk 脚本之外有一些引用和其他问题。
无论如何,这似乎就是您想要做的(未经测试):
for csv in "${_in_path}${_letter}_"*_*'.csv.gz'; do
zcat "$csv" |
sort -t',' -T tmp -k4 |
awk -F ',' '
!= key {
close(out)
key =
fn = "requests_by_IP/" key ".csv.gz"
out = "gzip >> " fn
}
{ print | out }
'
done
我遇到了一个问题,希望有人能帮助我。
我需要读取一个 gzip 压缩的大日志文件,对于读取的每一行,获取特定字段并根据该字段的值创建或将整行附加到该文件(gzip 压缩)。
最初我没有创建行或将行附加到 gzip 文件,但服务器上确实没有足够的 space,所以,我需要这样做。
由于在 AWK 中使用 gzip,使用管道和引号,结束部分(关闭文件)停止工作。
我试图将此关闭文件移动到 AWK 的开头,但我一直收到此消息(打开的文件太多消息。
在中间使用 gzip 之前,AWK 一切正常。
有效但不附加到 gzip 文件:
for _csv in $( ls ${_in_path}${_letter}_*_*.csv.gz ); do
zcat $_csv | sort -t',' -T tmp -k4 | awk -F "," '{ _key = ; _fn = "requests_by_IP/"_key".csv"; printf "%s\n", [=10=] >> _fn; close(_fn)}'
done
无效:
for _csv in $( ls ${_in_path}${_letter}_*_*.csv.gz ); do
zcat $_csv | sort -t',' -T tmp -k4 | awk -F "," '{ if (!_fn) { close(_fn); } _key = ; _fn = "requests_by_IP/"_key".csv.gz"; printf "%s\n", [=11=] | "gzip >> "_fn;}'
done
for _csv in $( ls ${_in_path}${_letter}_*_*.csv.gz ); do
zcat $_csv | sort -t',' -T tmp -k4 | awk -F "," ' _key = ; _fn = "requests_by_IP/"_key".csv.gz"; printf "%s\n", [=12=] | "gzip >> "_fn; close(_fn);}'
done
注意:如果我不在引号内使用 gzip 命令 ("gzip >> "),我会在 > error[=14= 处或附近收到此通用 语法错误]
编辑:非常感谢@edmorton!特别是 https://www.shellcheck.net/ 提示 !!!
awk 的输出是 "gzip >> "_fn
的管道,而不是名称存储在 _fn
中的文件,因此 that 是您需要的关闭,例如close("gzip >> "_fn)
。您应该 copy/paste 您的 shell 脚本到 http://shellcheck.net 并修复它首先告诉您的问题,因为您在 awk 脚本之外有一些引用和其他问题。
无论如何,这似乎就是您想要做的(未经测试):
for csv in "${_in_path}${_letter}_"*_*'.csv.gz'; do
zcat "$csv" |
sort -t',' -T tmp -k4 |
awk -F ',' '
!= key {
close(out)
key =
fn = "requests_by_IP/" key ".csv.gz"
out = "gzip >> " fn
}
{ print | out }
'
done