行の中央にあるキーワードの後ろの対応する行から値のみを取得します。

行の中央にあるキーワードの後ろの対応する行から値のみを取得します。

こんにちは、ファイルの途中に次の行があり、「energy =」の後にある値を取得する必要があります。行番号は「lineNumber」という変数に格納されます。ファイルの構造は同じですが、値が異なる別の行があります。私は "lineNumber"で定義されたラインのエネルギー値だけが欲しいです。助けてくれてありがとう。ありがとうございます!

Properties=species:S:1:pos:R:3:velocities:R:3:forces:R:3:local_energy:R:1:fix_atoms:S:3 Lattice="42.0000000000       0.0000000000    0.0000000000    0.0000000000   46.0000000000    0.0000000000    0.0000000000    0.0000000000   50.0000000000" temperature=327.11679001 pressure=14.24003276 time_step=5.0000 time=5000.0000 energy=-18.022194 virial="0.46990039            0.48760331     -0.77576961      0.48760331      0.78141847      0.59471844     -0.77576961      0.59471844      0.64787347" stress="-0.00000486          -0.00000505      0.00000803     -0.00000505     -0.00000809     -0.00000616      0.00000803     -0.00000616     -0.00000671" volume=96600.000000 step=1000

ベストアンサー1

Linuxベースのシステムを使用しているので、GNUを使用していることはほぼ確実です。grep

grep -oP 'energy=\K[^\s]+'

例えば

echo 'Properties=species:S:1:pos:R:3:velocities:R:3:forces:R:3:local_energy:R:1:fix_atoms:S:3 Lattice="…" temperature=327.11679001 … time=5000.0000 energy=-18.022194 virial="0.46990039 …" stress="…" volume=96600.000000 step=1000' |
    grep -oP 'energy=\K[^\s]+'

出力

-18.022194

次のようなものを使用できますsed

lineNumber=123
sed -n "${lineNumber}{p;q}" file

これらを総合すると、

sed -n "${lineNumber}{p;q}" file | grep -oP 'energy=\K[^\s]+'

次のものを使用することもできますperl

perl -e '
    $lineNumber = shift;                                 # Arg 1 is line number
    $fieldName = shift;                                  # Arg 2 is field name
    while (defined($line = <>)) {                        # Read lines from file or stdin
        next unless $. == $lineNumber;                   # Skip until required line
        chomp $line;                                     # Discard newline
        %a =                                             # Create key/value array. Read the next lines upwards
            map { split(/=/, $_, 2) }                    # 3. Split into {key,value} tuples
            grep { /=/ }                                 # 2. Only interested in assignments
            split(/(\w+=(".*?"|[^"].*?)\s+)/, $line);    # 1. Split line into « key=value » and « key="several values" » fields
        print $a{$fieldName}, "\n";                      # Print chosen field value
        exit 0
    }
' "$lineNumber" 'energy' file

おすすめ記事