我有两个文件(fileA和fileB)。 FileA包含数字列表,fileB包含数字范围。
的fileA
446646452
000000001
63495980020
fileB(range_from和range_to)
22400208, 22400208
446646450, 446646450
63495980000, 63495989999
输出必须
63495980020
在sql脚本中就像
一样 select *
from fileB
where 446646452 between Range_from and Range_To
如何使用shell脚本执行此操作?
答案 0 :(得分:2)
$ awk 'FNR==NR{low[NR]=$1+0; hi[NR]=$2+0;next} {for (i in low)if ($1>low[i] && $1<hi[i]){print $1;next}}' fileB fileA
63495980020
FNR==NR{low[NR]=$1+0; hi[NR]=$2+0;next}
在第一个文件fileB
中读取时,保存数组low
中范围的低端和数组hi
中的高端。
for (i in low)if ($1>low[i] && $1<hi[i]){print $1;next}
在第二个文件fileA
中读取时,请检查每个范围的数字。如果它满足任何范围,则打印并跳至next
行。
$ paste fileA fileB | awk '$1>$2+0 && $1<$3+0{print $1}'
63495980020
请注意,仅打印63495980020。 446646452不在22400208和22400208之间,因此省略。
实用程序paste
组合了以下文件:
$ paste fileA fileB
446646452 22400208, 22400208
000000001 446646450, 446646450
63495980020 63495980000, 63495989999
第一列是我们感兴趣的数字,而第二列是范围的低值,第三列是高值。我们想打印第一个值$1
,如果它在第二个和第三个之间。为了测试它是否大于第二个,我们可能会尝试:
$1>$2
但是,为了确保awk
将字段视为数字而不是字符串,我们对其中一个数字执行加法:
$1>$2+0
同样,要测试第一个数字是否小于第三个数字:
$1<$3+0
将这两个测试与打印命令放在一起产生:
$1>$2+0 && $1<$3+0 {print $1}
此测试在之间严格执行。根据您的要求,您可能更愿意:
$1>=$2+0 && $1<=$3+0 {print $1}
答案 1 :(得分:2)
根据OP的说明,fileA
中的每个值都应根据fileB
中的所有范围进行检查,以查看它是否属于至少一个范围。
假定范围检查的>=
和<=
逻辑(即,包括与范围端点一致的值)。
awk -F', +' '
# 1st pass (fileB): read the lower and upper range bounds
FNR==NR { lbs[++count] = $1+0; ubs[count] = $2+0; next }
# 2nd pass (fileA): check each line against all ranges.
{
for(i=1;i<=count;++i) {
if ($1+0 >= lbs[i] && $1+0 <= ubs[i]) { print; next }
}
}
' fileB fileA
awk
用于使用单独的传递读取两个文件:
FNR==NR
适用于fileB
的所有行;建立了范围下界(lbs
)和上界(ubs
)的并行数组;感谢next
,对fileB
行没有进一步处理。{...}
块仅适用于fileA
。fileA
中的每个值,一旦找到匹配项,就会打印输入行,处理进入下一行。+0
。答案 2 :(得分:1)
旧时尚剧本
sed 's/,[[:space:]]*/ /' fileB \
| while read LowVal HighVal
do
while read ThisLine
do
[ ${ThisLine} -ge ${LowVal} ] && [ ${ThisLine} -le ${HighVal} ] && echo "${ThisLine}"
done < fileA
done