bash - for 循环内的 AWK 条件状态返回比预期更多的结果
问题描述
大家好,我正在尝试制作一个矩阵,如果它满足条件则打印一个元素,如果它不满足它,则打印一个字符。文件如下:names.txt
name1
name2
name3
name4
name5
name6
name7
nthits.txt
name1 1 hits found
name2 2 hits found
name3 2 hits found
name4 4 hits found
name5 4 hits found
name6 2 hits found
name7 2 hits found
phits.txt
name7 1 hits found
我使用的代码是:
NAMES=$(cat names.txt)
for NAME in $NAMES; do
HITS_NT=$(awk -F" " -v NAME=$NAME '{if ($1 == NAME) {print $2} else {print "0"}}' nthits.txt)
HITS_AA=$(awk -F" " -v NAME=$NAME '{if ($1 == NAME) {print $2} else {print "0"}}' phits.txt)
echo -e $NAME"\t"$HITS_NT"\t"$HITS_AA
done
预期的结果是这样
name1 1 0
name2 2 0
name3 2 0
name4 4 0
name5 4 0
name6 2 0
name7 2 1
但是在执行它时,它会打印出比预期更多的字符。
name1 1 0 0 0 0 0 0 0
name2 0 2 0 0 0 0 0 0
name3 0 0 2 0 0 0 0 0
name4 0 0 0 4 0 0 0 0
name5 0 0 0 0 4 0 0 0
name6 0 0 0 0 0 2 0 0
name7 0 0 0 0 0 0 2 1
有什么建议或建议吗??非常感谢。
解决方案
首先,只需一次awk
调用即可。
$: awk 'FILENAME == "names.txt" { print $0 "\t" lookup["nthits.txt"$0]+0 "\t" lookup["phits.txt"$0]+0 }
{ lookup[ FILENAME $1 ]=$2 }' nthits.txt phits.txt names.txt
name1 1 0
name2 2 0
name3 2 0
name4 4 0
name5 4 0
name6 2 0
name7 2 1
其次,尽量避免使用for
循环读取文件。这个构造:
NAMES=$(cat names.txt)
for NAME in $NAMES; do
容易出错。如果使用bash
,请尝试以下操作:
while read -r name; do
# . . .
done < names.txt
awk
是更好的工具,但是要在纯脚本中执行相同的操作,请完全bash
消除awk
,因为重复的子进程生成实际上会减慢它的速度。
declare -A nthits phits
while read -r name hits _; do nthits[$name]=$hits; done < nthits.txt
while read -r name hits _; do phits[$name]=$hits; done < phits.txt
while read -r name; do
printf "%s\t%s\t%s\n" "$name" "${nthits[$name]:=0}" "${phits[$name]:=0}"
done < names.txt
输出中的额外字段是因为您对每一行都进行了多重处理。您正在遍历 names.txt 中的每个名称,并为每个名称创建 nthits.txt 和 phits.txt 的每一行的输出。随着这些文件变大(更多记录),您应该注意到输出中列的相应增长。要执行您尝试执行的操作,您应该在每次调用 awk 时仅选择循环中的当前名称。
为此,您应该使用
awk -v name=$NAME '$1 == name {print $2}' nthits.txt
它仍然会读取每一行,但不会为不匹配的那些生成输出。如果没有匹配项,这仍然不会产生 0,所以你需要类似的东西
awk -v name=$NAME 'BEGIN{ out=0 } $1 == name { out=$2 } END{ print out }' nthits.txt
而且您仍然必须打印名称和选项卡...尽管如此
,更容易awk
在顶部执行所有操作。:)
推荐阅读
- c# - 如何在 ASP.NET MVC 中将多个值保存到一个文本文件中
- sql - 从hierarchyID中的最后一个数字中提取最大值?
- php - 无限滚动、分页和路线
- vb.net - 在 vb.net 中的两种形式之间传递变量时遇到问题
- javascript - ExpressionChangedAfterItHasBeenCheckedError:表达式在从 ckEditor 获取值时被检查后已更改
- flutter - StatefullWidget 和 StatelessWidget 在性能方面有什么区别?
- git - Git - 给合并的分支一个标签
- spring-boot - How to create apache spark standalone cluster for integration testing using TestContainers?
- regex - 使用 sed GnuWin32 删除一行中的重复单词
- reactjs - 为什么我的 IconMenu 反应组件有错误?警告:未知的事件处理程序属性“onKeyboardFocus”。会被忽略