将几个文件的“awk”结果发送到具有相同名称的新文件

时间:2014-10-23 16:07:55

标签: linux bash awk

我有一个包含文本文件的文件夹。我需要在最后一个单词“输入”后提取20行,并将结果发送到不同文件夹中的同名文件

我使用以下内容:

for i in error/*.log; do awk '/Input/ {n=NR} {a[NR]=$0} END {for (i=n;i<=n+20;i++) print a[i]}' $i > exceeded/`basename $i` done

我做错了什么?

感谢您的帮助

4 个答案:

答案 0 :(得分:0)

我希望没有这方面的赞成票:

当我听到“在最后之后做一些事情......”时,我认为“在第一次*之后反转输入并做一些事情......”

这个awk只需要记住20行:如果你有大文件会有帮助。

for f in error/*.log; do
    tac "$f" | 
    awk -v n=20 -v pattern="input" '
        BEGIN { for (i=1; i<=n; i++) line[i] = "" }
        function keep_line(l) {
            for (i=2; i<=n; i++) line[i-1] = line[i]
            line[n] = l
        }
        $0 ~ pattern {
            for (i=1; i<=n; i++) print line[i]
            exit
        }
        { keep_line($0) }
    ' |
    tac > "exceeded/$(basename "$f")"
done

答案 1 :(得分:0)

如果文件名中有空格(* .log的*部分),请尝试:

for i in error/*.log; do awk '/Input/ {n=NR} {a[NR]=$0} END {for (i=n;i<=n+20;i++) print a[i]}' "$i" > "exceeded/`basename \"$i\"`" ; done

另外,我假设“错误”和“超出”目录都在同一目录中(“已超出”已存在。)

答案 2 :(得分:0)

这是怎么回事?

for i in error/*.log; do
  awk '/Input/ { i=21; delete a; next }
    --i > 0 { a[21-i] = $0 }
    END { for (i=1; i <=20; ++i) print a[i] }' "$i" >exceeded/"${i#error/}"
done

答案 3 :(得分:0)

for i in error/*.log; do
    awk 'NR==FNR{if(/Input/)n=NR;next} FNR>n && FNR<(n+21)' "$i" "$i" > exceeded/$(basename "$i")
done