bash - 使用 AWK 为日志添加前缀
问题描述
我遇到了需要用于日志分析的脚本的问题;让我解释一下这个问题:
我有一个 gzipped 文件,例如:
5555_prova.log.gz
在文件里面有这样的日志马里行:
2018-06-12 03:34:31 95.245.15.135 GET /hls.playready.vod.mediasetpremium/farmunica/2018/06/218742_163f10da04c7d2/hlsrc/w12/21.ts
我需要一个脚本来读取 gzipped 日志文件,该文件能够在标准输出上输出修改后的日志行,如下所示:
5555 2018-06-12 03:34:31 95.245.15.135 GET /hls.playready.vod.mediasetpremium/farmunica/2018/06/218742_163f10da04c7d2/hlsrc/w12/21.ts
如您所见,日志行现在以从 gzip 文件名中读取的数字开始。我需要这条新线来提供 logstash 数据处理链。
我试过这样的脚本:
echo "./5555_prova.log.gz" | xargs -ISTR -t -r sh -c "gunzip -c STR | awk '{$0="5555 "$0}' "
这不完全是我所需要的(前缀是静态的,不是用文件名中的正则表达式捕获的)但即使使用这个简化版本,我也会收到一个错误:
sh -c gunzip -c ./5555_prova.log.gz | awk '{-bash=5555 -bash}'
-bash}' : -c: line 0: unexpected EOF while looking for matching `''
-bash}' : -c: line 1: syntax error: unexpected end of file
正如您从上面的输出中看到的那样,$0
不再是通过管道传递给 awk 的整行而是一个奇怪 -bash
的.
我需要使用 xargs,因为 gzip 压缩文件的列表是从另一个工具(即实例化inotifywait
侦听通过 ftp 写入文件的目录)提供给命令行的。我错过了什么?您有什么建议可以为我指明正确的方向吗?
问候,S。
尝试遵循@Charles Duffy 的建议,我编写了以下代码:
#/bin/bash
#
# Usage: sendToLogstash.sh [pattern]
#
# Executes a command whenever files matching the pattern are closed in write
# mode or moved to. "{}" in the command is replaced with the matching filename (via xargs).
# Requires inotifywait from inotify-tools.
#
# For example,
#
# whenever.sh '/usr/local/myfiles/'
#
#
DIR="$1"
PATTERN="\.gz$"
script=$(cat <<'EOF'
awk -v filename="$file" 'BEGIN{split(filename,array,"_")}{$0=array[1] OFS $0} 1' < $(gunzip -dc "$DIR/$file")
EOF
)
inotifywait -q --format '%f' -m -r -e close_write -e moved_to "$DIR" \
| grep --line-buffered $PATTERN | xargs -I{} -r sh -c "file={}; $script"
但我得到了错误:
[root@ms-felogstash ~]# ./test.sh ./poppo
gzip: /1111_test.log.gz: No such file or directory
gzip: /1111_test.log.gz: No such file or directory
sh: $(gunzip -dc "$DIR/$file"): ambiguous redirect
感谢您的帮助,我在编写 bash 脚本时感到很失落。
问候,S。
解决方案
编辑:另外,如果您正在处理多个.gz
文件并想要打印它们的内容以及它们的文件名(第一列 _ 分隔),那么以下内容可能会对您有所帮助。
for file in *.gz; do
awk -v filename="$file" 'BEGIN{split(filename,array,"_")}{$0=array[1] OFS $0} 1' <(gzip -dc "$file")
done
我还没有测试你的代码(也不能完全理解),所以尝试在这里提供一种方式,以防你的代码可以将文件名传递给awk
然后附加文件的第一个数字,如下所示(只是一个例子)。
awk 'FNR==1{split(FILENAME,array,"_")} {$0=array[1] OFS $0} 1' 5555_prova.log_file
所以在这里我FILENAME
从盒子变量中取出awk
(仅在文件的第一行),然后将其拆分为名为数组的数组,然后将其添加到文件的每一行中。
在将其输出传递给之前,也可以用似乎丢失"gunzip -c STR
的结尾来包装它。"
awk
推荐阅读
- c++ - 我如何误解有关“可简单复制”的 C++ 标准?
- python - 需要一种有效的方法来使用 Python 按名称对 hdf5 文件中的数据集进行计数
- javascript - 上传图片到推特失败
- php - 无法使用 PHP 代码从轮播/滑块/幻灯片中抓取所有图像使用 PHP 简单 HTML DOM 解析器
- docker - Docker Private Registry:连接被拒绝
- mysql - 如何在mysql中创建按日期分组的值计数?
- html - 如何使用 svg 图像可点击区域和带有 jquery 的关闭按钮来显示和隐藏 div,一次只能看到一个 div
- r - 使用 r 中的公式将 mutate 与条件语句相结合
- typescript - 设置自定义 terserOptions 会禁用最小化器?
- python - Python 中的 For 循环: