我如何遍历 .log 文件,通过 awk 处理它们,并替换为具有不同扩展名的输出文件?
How can I iterate over .log files, process them through awk, and replace with output files with different extensions?
假设我们在 prod unix 机器 (Sunos) 的一个目录中有多个 .log 文件:
例如:
ls -tlr
total 0
-rw-r--r-- 1 21922 21922 0 Sep 10 13:15 file2017-01.log
-rw-r--r-- 1 21922 21922 0 Sep 10 13:15 file2016-02.log
-rw-r--r-- 1 21922 21922 0 Sep 10 13:15 todo2015-01.log
-rw-r--r-- 1 21922 21922 0 Sep 10 13:15 fix20150223.log
这里的目的是通过 nawk 我从日志中提取特定信息(解析日志)并将它们 "transform" 到 .csv 文件,以便之后将它们加载到 ORACLE 表中。
虽然 nawk 已经过测试并且工作起来非常棒,但我如何才能自动执行执行以下操作的 bash 脚本:
1) 对于此路径中给定文件的列表
2) nawk(从日志文件中提取特定的 data/info)
3) 将每个文件分别输出到唯一的.csv到另一个目录
4) 从此路径中删除 .log 文件
让我担心的是每个文件结尾的 loadstamp/timestamp 是不同的。我已经实现了一个只适用于最新日期的脚本。 (例如,上个月)。但是我想加载所有历史数据,我有点卡住了。
可视化,我的 desired/target 输出是这样的:
bash-4.4$ ls -tlr
total 0
-rw-r--r-- 1 21922 21922 0 Sep 10 13:15 file2017-01.csv
-rw-r--r-- 1 21922 21922 0 Sep 10 13:15 file2016-02.csv
-rw-r--r-- 1 21922 21922 0 Sep 10 13:15 todo2015-01.csv
-rw-r--r-- 1 21922 21922 0 Sep 10 13:15 fix20150223.csv
这个bash脚本如何实现?加载只需要一次,如前所述,它是历史性的。
任何帮助都可能非常有用。
为可读性而不是简洁而编写的实现可能如下所示:
#!/usr/bin/env bash
for infile in *.log; do
outfile=${infile%.log}.csv
if awk -f yourscript <"$infile" >"$outfile"; then
rm -f -- "$infile"
else
echo "Processing of $infile failed" >&2
rm -f -- "$outfile"
fi
done
要了解其工作原理,请参阅:
- Globbing -- 将
*.log
替换为具有该扩展名的文件列表的机制。
- The Classic
for
Loop -- for infile in
语法,用于迭代上述 glob 的结果。
- Parameter expansion --
${infile%.log}
语法,用于扩展带有任何 .log
后缀 p运行ed 的 infile
变量的内容。
- Redirection --
<"$infile"
和 >"$outfile"
中使用的语法,打开附加到命名文件的标准输入和标准输出;或 >&2
,将日志重定向到 stderr。 (因此,当我们 运行 awk
时,它的标准输入连接到一个 .log
文件,它的标准输出连接到一个 .csv
文件。
假设我们在 prod unix 机器 (Sunos) 的一个目录中有多个 .log 文件: 例如:
ls -tlr
total 0
-rw-r--r-- 1 21922 21922 0 Sep 10 13:15 file2017-01.log
-rw-r--r-- 1 21922 21922 0 Sep 10 13:15 file2016-02.log
-rw-r--r-- 1 21922 21922 0 Sep 10 13:15 todo2015-01.log
-rw-r--r-- 1 21922 21922 0 Sep 10 13:15 fix20150223.log
这里的目的是通过 nawk 我从日志中提取特定信息(解析日志)并将它们 "transform" 到 .csv 文件,以便之后将它们加载到 ORACLE 表中。 虽然 nawk 已经过测试并且工作起来非常棒,但我如何才能自动执行执行以下操作的 bash 脚本:
1) 对于此路径中给定文件的列表
2) nawk(从日志文件中提取特定的 data/info)
3) 将每个文件分别输出到唯一的.csv到另一个目录
4) 从此路径中删除 .log 文件
让我担心的是每个文件结尾的 loadstamp/timestamp 是不同的。我已经实现了一个只适用于最新日期的脚本。 (例如,上个月)。但是我想加载所有历史数据,我有点卡住了。
可视化,我的 desired/target 输出是这样的:
bash-4.4$ ls -tlr
total 0
-rw-r--r-- 1 21922 21922 0 Sep 10 13:15 file2017-01.csv
-rw-r--r-- 1 21922 21922 0 Sep 10 13:15 file2016-02.csv
-rw-r--r-- 1 21922 21922 0 Sep 10 13:15 todo2015-01.csv
-rw-r--r-- 1 21922 21922 0 Sep 10 13:15 fix20150223.csv
这个bash脚本如何实现?加载只需要一次,如前所述,它是历史性的。 任何帮助都可能非常有用。
为可读性而不是简洁而编写的实现可能如下所示:
#!/usr/bin/env bash
for infile in *.log; do
outfile=${infile%.log}.csv
if awk -f yourscript <"$infile" >"$outfile"; then
rm -f -- "$infile"
else
echo "Processing of $infile failed" >&2
rm -f -- "$outfile"
fi
done
要了解其工作原理,请参阅:
- Globbing -- 将
*.log
替换为具有该扩展名的文件列表的机制。 - The Classic
for
Loop --for infile in
语法,用于迭代上述 glob 的结果。 - Parameter expansion --
${infile%.log}
语法,用于扩展带有任何.log
后缀 p运行ed 的infile
变量的内容。 - Redirection --
<"$infile"
和>"$outfile"
中使用的语法,打开附加到命名文件的标准输入和标准输出;或>&2
,将日志重定向到 stderr。 (因此,当我们 运行awk
时,它的标准输入连接到一个.log
文件,它的标准输出连接到一个.csv
文件。