GNU/Linux >> Linux の 問題 >  >> Linux

値が欠落している新しい行を挿入しますか(na)?

値が欠落している場合は、テキストファイルに新しい行を挿入したいと思います。
たとえば、次のテキストファイル(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に到達するために必要な欠落行があれば印刷されます。

関連:シェルスクリプトでタイムアウトしますか?
Linux
  1. Nmapを使用して新しいネットワークを列挙する

  2. 行の範囲を行の範囲(sedまたはその他)に置き換えますか?

  3. Linuxの「cat」コマンドを使用して、特定の行のみを番号で表示するにはどうすればよいですか。

  1. パターンに一致する行を別のファイルの行に順番に置き換えますか?

  2. 特定の行でOsxインサートをSedしますか?

  3. 1つのフィールドに重複する値があるCsvの連続する行を削除しますが、最後の行は保持しますか?

  1. 重複、わずかな変更、テキストファイルの数行?

  2. Linuxシェルスクリプトに新しい行を挿入するには?

  3. sed - 一致後に X 行の後に行を挿入する