我正在尝试执行系统命令,以查找csv文件在其前七个字符中有多少唯一引用,作为处理相同csv文件的较大awk脚本的一部分。有重复的条目,我不希望awk解析整个文件两次,所以我避免NR。脚本这一部分的要点是:
#!/bin/bash
awk '
{
#do some stuff, then when finished, count the number of unique references
productFile="BusinessObjects.csv";
systemCall = sprintf( "cat %s | cut -c 1-7 | sort | uniq | wc -l", $productFile );
productCount=`system( systemCall )`-1; #subtract 1 to remove column label row
}' < BusinessObjects.csv
翻译不喜欢它:
awk: cmd. line:19: ^ syntax error ./awkscript.sh: line 38: syntax error near unexpected token '('
./awkscript.sh: line 38: systemCall = sprintf( "cat %s | cut -c 1-7 | sort | uniq | wc -l", $productFile );
如果我硬编码系统命令
productCount=`system( "cat BusinessObjects.csv | cut -c 1-7 | sort | uniq | wc -l" )`-1;
我明白了:
./awkscript.sh: command substitution: line 39: syntax error near unexpected token '"cat BusinessObjects.csv | cut -c 1-7 | sort | uniq | wc -l"'
./awkscript.sh: command substitution: line 39: 'system( "cat BusinessObjects.csv | cut -c 1-7 | sort | uniq | wc -l" )'
从技术上讲,我可以在shell脚本开始时在awk之外执行此操作,将结果存储在系统变量中,然后使用-v将其传递给awk,但这对于awk脚本的可读性并不好(这是几百行长)。我在错误的地方有空格或引号吗?我试过摆弄,但我似乎无法以解释器接受的方式呈现对system()的调用。最后,还有更合理的方法吗?
编辑: csv文件确实是以分号分隔的,所以最好使用分隔符而不是字符数来剪切(谢谢!)。
ProductRef;数据1;数据2;等等
1234567;等;等;等等
编辑2: 我正在尝试解析第一列充满N个唯一产品引用的csv文件,并创建一系列包含“Page n of N”信息字段的关联HTML页面。很明显,这是我第一次使用awk,但它似乎是解析csv文件的合适工具。我正在尝试计算并返回唯一引用的数量。在shell
cut -d \; -f1 BusinessObjects.csv |排序| uniq | wc -l </ p>
工作正常,但我无法通过
让它在awk中运行#!/bin/bash
if [ -n "$1" ]
then
productFile=$1
else
echo "Missing product file argument."
exit
fi
awk -v productFile=$productFile '
BEGIN {
FS=";";
productCount = 0;
("cut -d\"\;\" -f1 " productFile " | sort | uniq | wc -l") | getline productCount;
productCount -=1; #remove the column label row
}
{
print productCount;
}'
如果我没有将分号包装在\“\; \”中,我会在剪切代码上出现语法错误,而且当我这样做时,脚本会挂起而不打印任何内容。
答案 0 :(得分:1)
我不记得你可以在awk中使用反引号。
productCount=`system( systemCall )`-1; #subtract 1 to remove column label row
您可以通过不使用系统并直接运行命令来读取输出,而是使用getline:
systemCall | getline productCount
productCount -= 1
或者更完整
productFile = "BusinessObjects.csv"
systemCall = "cut -c 1-7 " productFile " | sort | uniq | wc -l"
systemCall | getline productCount
productCount -= 1
sprintf
并包含cat
。"xyz" | getline ...
。sort | uniq
可以sort -u
。getline
可能会改变全局变量与预期不同。见https://www.gnu.org/software/gawk/manual/html_node/Getline.html。答案 1 :(得分:0)
这样的事情可以选择吗?
$ cat productCount.sh
#!/bin/bash
if [ -n "$1" ]
then
productCount=`cat $1 | cut -c 1-7 | sort | uniq | wc -l`
echo $productCount
else
echo "please supply a filename as parameter"
fi
$ ./productCount.sh BusinessObjects.csv
9