linux awk 写文件,linux – 如何将awk结果输出到文件

本文介绍了在Linux shell脚本中使用awk处理CSV文件时遇到的输出重定向问题。问题在于awk命令内的字符串引用未正确处理,导致无法按预期将结果写入指定目录下的文件。解决方案是使用awk的 `-v` 选项传递变量,并确保在awk脚本中正确引用目录名,以便在匹配时作为字符串比较。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我试图在我的脚本中输出’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 -F, -v a=$a '{ if ($10==a) print $0 }' ...

然后变量成为一流的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选项时,命令:

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的变化),我得到:

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和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,我得到:

tmp is a directory

NO

tmp2 is a directory

NO

那是因为awk将if语句看作:

if ($10 == tmp) {

(没有引号,因为引号实际上在用于包围目录名称的awk字符串之外).对于名为tmp的awk变量而不是实际的字符串“tmp”,这将测试10美元.你需要的是确保引号在awk脚本中,如:

if ($10 == "tmp") {

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

#!/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附近保留双引号以防万一有人犯下了创造一个带有空格的文件的令人发指的罪行:-)

运行该脚本会产生:

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 }'

至:

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

它应该运作正常.

标签:bash,linux,scripting,awk

来源: https://codeday.me/bug/20190607/1191734.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值