sed正規表現を使用して数値部分のみをキャプチャする

sed正規表現を使用して数値部分のみをキャプチャする

次はなぜ機能しないのですか?

INTERNAL_NUM=$(grep -E '\s*internal_num\s*=' file.xml |sed -E 's/internal_num\s*=\s*([0-9]\+)/\1/') 
echo "$INTERNAL_NUM"

実際の数字を印刷したいのですが、次のように印刷されます。

internal_num = 1234 

コマンドgrepはを印刷するため、internal_num = 1234その部分は正常です。sed動作しないパイプです。

答え1

GNU grepがあれば、次のように書くことができます。

grep -oP '\binternal_num\s*=\s*\K\d+' file.xml

ただし、正規表現を使用してXMLを解析しないでください。たぶん、このようなことが必要かもしれません。

$ echo '
      <root>
          <tag>
              <tag>
                  <wanted internal_num="1234" />
                  <wanted internal_num = "5678" />
              </tag>
          </tag>
      </root>
  ' | xmlstarlet sel -t -v '//@internal_num' -n
1234
5678

入力ファイルを見せてください。

答え2

さまざまなツールと特定のツールの実装/バージョンは、さまざまな正規表現構文をサポートします。

移植性のために、POSIX機能セットに制限できます。

s=[[:space:]]
sed -n "s/^\(.*$s\)\{0,1\}internal_num$s*=$s*\([0-9]\{1,\}\).*/\2/p"

(各行が一度だけ現れると仮定)

grepGNUをサポートするシステムでのみ実行-oし(Perlに似た正規表現の場合)、次のことができることがわかっている場合は、次のようにできます。-Pgrep

grep -Po '(?<!\S)internal_num\s*=\s*\K\d+'

答え3

拡張正規表現を使用していますが、まだエスケープしているので、\+リテラルプラス記号を探して置換を呼び出すことはありません。

努力する、

INTERNAL_NUM=$(grep -E '\s*internal_num\s*=' file.xml |sed -E 's/internal_num\s*=\s*([0-9]+)/\1/') 
echo "$INTERNAL_NUM"

テストケース(GNU sed V4.2.1でテスト済み):

$ echo "internal_num = 1234" | sed -E 's/internal_num\s*=\s*([0-9]\+)/\1/'
internal_num = 1234

$ echo "internal_num = 1234" | sed -E 's/internal_num\s*=\s*([0-9]+)/\1/'
1234

他の回答で述べて詳細に説明したように、正規表現を使用してXMLを解析しないことを真剣に検討する必要があります。

関連情報