値が欠落している場合は、テキストファイルに新しい行を挿入したいと思います。
たとえば、次のテキストファイル(A.txt)がありますが、5行目が欠落しています。さらに、ファイルには12行あるはずなので、11〜12行も欠落しています。
1 2.30
2 3.01
3 3.22
4 3.34
6 3.01
7 2.90
8 2.99
9 3.00
10 3.02
私の期待する出力は次のとおりです。欠落している場合は、番号とNAを含む行を追加する必要があります。ご覧のとおり、これは5、11、12行目で希望どおりに発生しました:
1 2.30
2 3.01
3 3.22
4 3.34
5 NA
6 3.01
7 2.90
8 2.99
9 3.00
10 3.02
11 NA
12 NA
次のスクリプトを使用してこれを行うことができます:
f1=/my-directory/
echo "new file" > "$f1"/newfile.txt
for i in {1..12}; do
l=$(awk '{print $1}' /"$f1"/A.txt | grep -wE ^$i /"$f1"/A.txt)
if grep --quiet -wE ^$i /"$f1"/A.txt; then echo "$l" >> "$f1"/newfile.txt; else echo "$i NA" >> "$f1"/newfile.txt; fi
done
これは正常に機能します。ただし、問題は、約160000行を超える約600ファイルに対してこれを行う必要があることです。したがって、ループソリューションでは、すべての行を検索するのに時間がかかりすぎます。私の質問は、これを行うことができるより簡単な解決策はありますか?
承認された回答:
これはawk
で行うことができます スクリプト:
awk '{ while (NR + shift < $1) { print (NR + shift) " NA"; shift++ }; print } END { shift++; while (NR + shift < 13) { print (NR + shift) " NA"; shift++ } }' /tmp/test1
/tmp/test1
に必要な出力を生成します (処理する各ファイルに置き換えてください)。
より読みやすい形式で:
#!/usr/bin/awk -f
{
while (NR + shift < $1) {
print (NR + shift) " NA"
shift++
}
print
}
END {
shift++
while (NR + shift < 13) {
print (NR + shift) " NA"
shift++
}
}
これをファイルとして保存します。たとえば、fill-missing
、実行可能にすると、簡単に実行できます
./fill-missing /tmp/test1
スクリプトは各行を処理し、shift
の現在の行番号で予想されるデルタを追跡します 。したがって、すべての行について、調整された現在の行が行の最初の番号と一致しない場合、適切な行番号に続いてNA
が出力されます。 デルタをインクリメントします。行番号が一致すると、現在の行が出力されます。プロセスの最後に、12に到達するために必要な欠落行があれば印刷されます。