Linux 如何将awk结果输出到文件

Linux 如何将awk结果输出到文件,linux,bash,scripting,awk,Linux,Bash,Scripting,Awk,我正在尝试将“awk”结果输出到脚本中的文件,但没有成功。 使用“>”不起作用,为什么 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/

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

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的一个功能,考虑到它的使用量,如果您在其中发现一个bug,我会非常惊讶:-)

您确定您没有尝试使用
awk
本身而不是shell进行重定向吗

当您执行以下操作时会发生什么:

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

更新:

如果这是如上所述的代码,那是因为shell脚本没有扩展
$a
,因为
awk
命令位于单引号内

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
,例如(在您的情况下):

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


进一步更新:

我支持我最初的建议。选择的方法肯定有点不对劲

我在我的主目录中有一个名为XpVm的目录(以及其他目录),我创建了一个文件
CDRNOutput_X.csv
,其中包含一行:

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
(我剥离了以
开头的目录,因为它们导致了另一个问题),我得到以下输出:

workspace is a directory
NO
Documents is a directory
NO
XpVm is a directory
NO
Downloads is a directory
NO
这显然不是人们所期望的。但是,当我按照最初的建议将
-v
选项用于
awk
时,命令:

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
的更改),我得到:

这是正确的


最后更新(希望):

我想问题已经解决了。我现在在另一台机器上(因此目录名只是
tmp
tmp2
),当我运行原始脚本时:

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
使用包含
tmp
而不是
XpVm
的修改后的
CDRNOutput_X.csv
,我得到:

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
tmp is a directory
NO
tmp2 is a directory
NO
这是因为
if
语句被
awk
视为:

        if ($10 == tmp) {
(不带引号,因为引号实际上位于用于环绕目录名的
awk
字符串之外)。这将测试
$10
是否与名为
tmp
awk
变量相等,而不是实际字符串
“tmp”
。您需要的是确保引号位于
awk
脚本中,如:

        if ($10 == "tmp") {
您可以使用以下脚本执行此操作(如果行已更改,则仅
):

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

运行该脚本将生成:

tmp is a directory
1,2,3,4,5,6,7,8,9,tmp,11
tmp2 is a directory
NO
这就是我认为你的目标

因此,结果是,如果不想使用
awk
变量,只需将awk字符串更改为:

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


而且它应该可以正常工作。

因为find命令的-mindepth和maxdepth设置为1,所以只需使用shell即可

#!/bin/bash
CDR_DATE="somedate"
infile=CDRNOutput_${CDR_DATE}.csv
outfile=CDR-${CDR_DATE}.csv
OUPUT_DIR="/some/dir"
cd $OUPUT_DIR
for dir in */
do
    echo "${dir%/*} is a directory"
    dir=${dir%/*}
    while read -r a b c d e f g h i j k
    do
        case "$j" in
            $dir) echo $a $b $c $d $e $f $g $h $i $j $k >> $dir/$outfile;;
        esac
    done < $infile
done
#/bin/bash
CDR_DATE=“somedate”
infle=CDRNOutput_${CDR_DATE}.csv
outfile=CDR-${CDR_DATE}.csv
OUPUT_DIR=“/some/DIR”
cd$OUPUT\U目录
对于dir in*/
做
echo“${dir%/*}是一个目录”
dir=${dir%/*}
而read-r a b c d e f g h j k
做
大写“$j”
$dir)echo$a$b$c$d$e$f$g$h$i$j$k>>$dir/$outfile;;
以撒
完成<$infle
完成

奇怪的是,
不起作用。你能给我们看一下你的代码吗?对于一个in$(find$output_DIR/-maxdepth 1-mindepth 1-type d-printf“%P\n”)来说,echo$a是一个awk-F目录,{如果($10='''$a“')print$0}'$output_DIR/CDRNOutput_${CDR_DATE csv>$output_DIR/$a/CDR-${CDR_DATE csv有什么办法不起作用?你有什么收获吗?正在创建的文件是否为空?等等…还有,您的CDRNOutput CSV文件的格式是什么?您的代码不显示
CDR\u日期
get set。此外,您已经说过几次“不起作用”,但您没有说过它在做什么。错误消息?空输出文件?输出文件在错误的位置?文件中的输出错误?如果省略重定向,是否会将正确的预期输出打印到屏幕上?@paxdiablo-该语句将结束单引号,然后用双引号将$a括起来,这样它就可以工作了。将awk更改为echo并尝试自己确认。实际上,awk还有一个重定向机制:awk{print>“filename”}写入一个名为filename的文件。尝试了这个命令:awk-F,-va=$a'{if($10==a)print$0}$output\u DIR/CDRNOutput\u${CDR\u DATE csv>$output\u DIR/$a/CDR-${CDR\u DATE csv仍然没有work@Jouni,该特定变体每次都会覆盖该文件,这不太可能是所需的@RSam,很好(尽管我还是喜欢我的)。但现在测试工作,我们需要更多的信息从OP。我使用-v(如前面的评论中提到的),但仍然不工作。我使用了'sex-X'以便查看命令,命令是:awk-F,-va=512543'{if($10==a)print$0}'/tmp/Camps/CDRNOutput_2010-01-01.csv
'{ if ($10 == '"$a"') print $0 }'
'{ if ($10 == "'"$a"'") print $0 }'
#!/bin/bash
CDR_DATE="somedate"
infile=CDRNOutput_${CDR_DATE}.csv
outfile=CDR-${CDR_DATE}.csv
OUPUT_DIR="/some/dir"
cd $OUPUT_DIR
for dir in */
do
    echo "${dir%/*} is a directory"
    dir=${dir%/*}
    while read -r a b c d e f g h i j k
    do
        case "$j" in
            $dir) echo $a $b $c $d $e $f $g $h $i $j $k >> $dir/$outfile;;
        esac
    done < $infile
done