私の入力ファイルは、行の長さが可変である単一の列です。私のコードはこの行を計算し、指定された数字を印刷する必要があります。私が持っている問題は、変数「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固有の機能を使用するには、スクリプトをshの代わりに起動する必要が#!/bin/bash
あります#!/bin/sh
。
((…))
Shには算術式の構文はありません。ただし、ここでは必要ではなく、移植可能な条件構文を使用できます[ … ]
。[ … ]
条件文には「より小さい」演算子を書き込みます-lt
。
中かっこは{1..2}
sh に存在しない別の bash 関数です。スクリプトのもう一つの間違いは、if is値と同様に文字列にX=$A+1
設定されることです。算術計算を実行するには、算術式構文を使用する必要があります。X
42+1
A
42
$((…))
また、一般的な意見では、変数の置換には常に二重引用符を使用してください。。
コードの他の問題は、10進数のようA
に見えることです。シェル操作は整数でのみ機能します。アルゴリズムを調整しましたが、どのように動作するかを確認すると、目的の方法に丸められない可能性があります。 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