如何将awk结果输出到文件 [英] How to output awk result to file

查看:2272
本文介绍了如何将awk结果输出到文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将'awk'结果输出到我的脚本文件中,但没有成功. 使用'>'不起作用,为什么?

I am trying to output 'awk' result to file in my script, with no success. Using '>' does not work, why?

for a in $(find $OUPUT_DIR/ -maxdepth 1 -mindepth 1 -type d -printf "%P\n")
do
    echo $a is a directory
    awk -F, '{ if ($10 == '"$a"') print $0 }' $OUPUT_DIR/CDRNOutput_${CDR_DATE}.csv > $OUPUT_DIR/$a/CDR-${CDR_DATE}.csv
done 

推荐答案

输出重定向通常是您正在使用的Shell的功能,并且,鉴于它得到了多少使用,如果您愿意,我会非常惊讶在其中发现了一个错误:-)

Output redirection is generally a feature of the shell you're working with and, given how much use it gets, I'd be pretty amazed if you'd found a bug in it :-)

您确定不尝试使用awk本身而不是外壳进行重定向吗?

Are you sure you're not trying to do redirection with awk itself rather than the shell?

操作时会发生什么:

echo 'hello' | awk '{print}' >qq.tmp


更新:

如果这是您所声明的代码,那是因为awk命令在单引号内,因此您的shell脚本没有扩展$a.

If this is your code as stated, it's because the $a is not being expanded by your shell script since the awk command is within single quotes.

for a in $(find $OUPUT_DIR/ -maxdepth 1 -mindepth 1 -type d -printf "%P\n")
do
    echo $a is a directory
    awk -F, '{ if ($10 == '"$a"') print $0 }' $OUPUT_DIR/CDRNOutput_${CDR_DATE}.csv > $OUPUT_DIR/$a/CDR-${CDR_DATE}.csv
done

我倾向于做的是使用-v选项将特定值传递给awk,类似(在您的情况下):

What I tend to do is pass in specific values to awk using the -v option, something like (in your case):

awk -F, -v a=$a '{ if ($10==a) print $0 }' ...

然后变量成为一流的awk公民,而不必担心谁在进行扩展.

Then the variables become first-class awk citizens without having to worry about who's doing the expansion.

进一步更新:

我支持我的原始建议.选择的方法肯定有些麻烦.

I'm standing behind my original advice. There's something definitely screwy with the method chosen.

我的主目录中有一个名为XpVm的目录(除其他外),并且创建了包含单行的文件CDRNOutput_X.csv:

I have a directory in my home directory called XpVm (among others) and I've created the file CDRNOutput_X.csv containing the single line:

1,2,3,4,5,6,7,8,9,XpVm,11

执行时:

for a in $(find . -maxdepth 1 -mindepth 1 -type d -printf "%P\n" | grep -v '^\.')
do
    echo $a is a directory
    awk -F, '{
        if ($10 == '"$a"') {
            print $0
        } else {
            print "NO";
        }
    }' ./CDRNOutput_X.csv
done

(我删除了以.开头的目录,因为它们引起了另一个问题),我得到以下输出:

(I've stripped out directories starting with . since they were causing another problem), I get this output:

workspace is a directory
NO
Documents is a directory
NO
XpVm is a directory
NO
Downloads is a directory
NO

这显然不是预期的.但是,如我最初建议的那样,当对awk使用-v选项时,命令:

which is clearly not what is expected. However, when I use the -v option to awk as I originally suggested, the command:

for a in $(find . -maxdepth 1 -mindepth 1 -type d -printf "%P\n" | grep -v '^\.')
do
    echo $a is a directory
    awk -F, -v a=$a '{
        if ($10 == a) {
            print $0
        } else {
            print "NO"
        }
    }' ./CDRNOutput_X.csv
done

(唯一的不同是对a的更改),我得到:

(the only difference being the changes to a), I get:

workspace is a directory
NO
Documents is a directory
NO
XpVm is a directory
1,2,3,4,5,6,7,8,9,XpVm,11
Downloads is a directory
NO

这是正确的.

最终更新(希望如此):

我认为问题已经解决.我现在在另一台计算机上(因此目录名称只是tmptmp2),并且当我运行原始脚本时:

I think I have the problem solved. I'm on a different machine now (so the directory names are simply tmp and tmp2) and, when I run the original script:

for a in $(find . -maxdepth 1 -mindepth 1 -type d -printf "%P\n" | grep -v '^\.')
do
    echo $a is a directory
    awk -F, '{
        if ($10 == '"$a"') {
            print $0
        } else {
            print "NO";
        }
    }' ./CDRNOutput_X.csv
done

经过修改的CDRNOutput_X.csv包含tmp而不是XpVm,我得到:

with a modified CDRNOutput_X.csv containing tmp instead of XpVm, I get:

tmp is a directory
NO
tmp2 is a directory
NO

这是因为awkif语句视为:

        if ($10 == tmp) {

(不带引号,因为引号实际上在内,而awk字符串用于包围目录名).这将针对名为tmpawk变量而不是实际的字符串"tmp",测试$10是否相等.您需要确保引号在脚本的 内,例如:

(without quotes, since the quotes are actually outside the awk string being used to surround the directory name). This will test $10 for equality against the awk variable called tmp rather than the actual string "tmp". What you need is to make sure that the quotes are inside the awk script, like:

        if ($10 == "tmp") {

,您可以使用以下脚本执行此操作(仅if行已更改):

and you can do this with the following script (only the if line has changed):

#!/bin/bash
for a in $(find . -maxdepth 1 -mindepth 1 -type d -printf "%P\n" | grep -v '^\.')
do
    echo $a is a directory
    awk -F, '{
        if ($10 == "'"$a"'") {
            print $0
        } else {
            print "NO";
        }
    }' ./CDRNOutput_X.csv
done

请注意双引号是重复的.我仍然在$a周围保留双引号,以防有人犯下了创建带有空格的文件的可怕罪行:-)

Note that the double quotes are duplicated. I've still kept the double quotes immediately around $a in case someone's committed the heinous crime of creating a file with a space in it :-)

运行该脚本会产生:

tmp is a directory
1,2,3,4,5,6,7,8,9,tmp,11
tmp2 is a directory
NO

这就是我想你要瞄准的.

which is what I think you were aiming for.

结果是,如果您不想使用awk变量,则可以从以下位置更改awk字符串:

So, the upshot is, if you don't want to use awk variables, you can just change your awk string from:

'{ if ($10 == '"$a"') print $0 }'

收件人:

'{ if ($10 == "'"$a"'") print $0 }'

它应该可以正常运行.

这篇关于如何将awk结果输出到文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆