我正在尝试将'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
答案 0 :(得分:6)
输出重定向通常是你正在使用的shell的一个特性,并且考虑到它有多少使用,如果你发现了一个bug,我会非常惊讶: - )
你确定你没有尝试用awk
本身而不是shell进行重定向吗?
当你这样做时会发生什么:
echo 'hello' | awk '{print}' >qq.tmp
更新
如果这是您所说的代码,那是因为$a
命令在单引号内,所以awk
没有被shell脚本扩展。
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
我倾向于使用awk
选项将特定值传递给-v
,类似于(在您的情况下):
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
选项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
的更改),我得到:
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
修改后的CDRNOutput_X.csv
包含tmp
而不是XpVm
,我得到:
tmp is a directory
NO
tmp2 is a directory
NO
这是因为if
awk
语句被 if ($10 == tmp) {
视为:
awk
(没有引号,因为引号实际上是外用于包围目录名称的$10
字符串)。这将测试awk
与名为tmp
的{{1}}变量的平等性,而不是实际的字符串"tmp"
。您需要确保引号 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 }'
它应该可以正常运作。
答案 1 :(得分:0)
因为你找到了-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