变量捕获和 For 循环运算

变量捕获和 For 循环运算

我的输入文件是行长度可变的单列。我的代码应该计算这些行,并打印指定的数字。我遇到的问题是,如果变量“A”中捕获的行数小于 1,我希望它至少打印 1 行,以便输出文件不为空。如果“A”(总行数的 1%)大于 1,我想打印该行数。我的混合 awk-bash 代码如下所示:

#!/bin/sh
for i in {1..2}
do
input="../ExpressionSet_"$i"_chunk.txt"
    for j in {1..2}
do

A=$(awk 'END{print NR*0.01}' $input)
Y=1
X=0
if (( "$A" -lt "$Y")); then
X=$A+1
else
X=$A

fi
awk 'NR<='$X' {print $0}' $input > "$i"_top1pc.txt

B=$(awk 'END{print NR*0.05}' $input) 
awk 'NR<='$B' {print $0}' $input > "$i"_top5pc.txt

令人困惑的是,我不断收到类似的错误消息

thresholdSelector_pc.sh: line 20: ((: 0.24 -lt 1: syntax error: invalid arithmetic operator (error token is ".24 -lt 1")
thresholdSelector_pc.sh: line 20: ((: 47.24 -lt 1: syntax error: invalid arithmetic operator (error token is ".24 -lt 1")

顺便说一句,inputFile1有24行,inputFile2有4724行。谢谢您的帮助!

答案1

我认为你的根本问题是你试图在 sh 脚本中使用 bash 语法。 Bash 定义了 sh 公分母的扩展;如果您想使用 bash 特定的功能,您的脚本必须以 开头#!/bin/bash,而不是#!/bin/sh

Sh 没有((…))算术表达式的语法。但这里不需要它,您可以使用可移植的[ … ]条件语法。在[ … ]条件句中,写有“小于”运算符-lt

大括号{1..2}是 sh 中不存在的另一个 bash 功能。脚本中的另一个错误是X=$A+1,它设置X为一个字符串,就像42+1if 的值A42;要执行算术计算,您需要使用算术表达式语法$((…))

另外,作为一般性评论,始终在变量替换周围使用双引号

您的代码的另一个问题是它看起来像是A一个十进制数。 Shell 算术仅适用于整数。我已经调整了算法,但检查了它的作用,我可能没有按照您想要的方式进行舍入。仅使用 awk 来计算行数就有点过分了,wc -l这是一种更清晰、更快的方法。同样,要打印文件的前 N ​​行,只需调用head.

另一个错误是$i_chunk变量的值i_chunk。要获取i并追加的值_chunk,您需要用大括号分隔变量名称:${i}_chunk

我不知道循环j应该做什么,我没有管它。

#!/bin/sh
for i in 1 2
do
  input="../ExpressionSet_${i}_chunk.txt"
  for j in 1 2
  do
    A=$(wc -l <"$input")
    Y=100
    X=0
    if [ "$A" -lt "$Y" ]; then
      X=$((A+100))
    else
      X=$A
    fi
    head -n "$((X/100))" "$input" > "$i"_top1pc.txt
    head -n "$((X/20))" "$input" > "$i"_top5pc.txt
  done
done

如果您选择编写 bash 脚本,则可以利用多个 bash 功能:

  • ((…))用于算术评估(但仍然仅限整数)
  • typeset -i声明一个整型变量,以便分配一个算术表达式来计算它
#!/bin/bash
for i in 1 2
do
  input="../ExpressionSet_${i}_chunk.txt"
  for j in 1 2
  do
    A=$(wc -l <"$input")
    Y=100
    typeset -i X
    if ((A < Y)); then
      X=A+100
    else
      X=$A
    fi
    head -n "$((X/100))" "$input" > "$i"_top1pc.txt
    head -n "$((X/20))" "$input" > "$i"_top5pc.txt
  done
done

相关内容