正規表現 - SQL操作

正規表現 - SQL操作
[pol@fedora data]$ lsb_release -a
LSB Version:    :core-4.1-amd64:core-4.1-noarch
Distributor ID: Fedora
Description:    Fedora release 34 (Thirty Four)
Release:    34
Codename:   ThirtyFour

MS SQL ServerのサンプルデータベースファイルをPostgreSQLに変換しようとしています。

それで、私が解決できない2つの小さな問題があります。

shipname       NVARCHAR(40) NOT NULL,

それは

  • いつも) 2つのスペース

  • 識別子(例:フィールド名) - 常に[az] - 小文字

  • その後に未知の数の空白が続きます。

  • NVARCHAR(xy) NOT NULL が続きます。またはNVARCHAR(xy) NULL が後に続くことがあります。

変えたい

shipname       TEXT NOT NULL CHECK (LENGTH(shipname)  <= xy),

または

shipname       TEXT NULL,

私が今まで持っているもの:

sed 's/^  [a-z]+[ ]+NVARCHAR([0-9]+) NOT NULL/TEXT NOT NULL CHECK \(LENGTH\((\1) <= (\2)\)/g'    

だから、

  • ^文字列の先頭です

  • 後ろに2つのスペース

  • 以下は私のフィールド名です。 [az]+

  • その後、ランダムな数字が続きます。スペース[ ]+

  • NVARCHAR([0-9]+)

そして代替

TEXTNOT NULL の後に CHECK(LENGTH(xy) - 逆参照 1 - <= 逆参照 2...

上記の内容をさまざまに変形して組み合わせてみましたが、何も私に合うようではありません。

[pol@fedora data]$ sed 's/^  [a-z]+[ ]+NVARCHAR([0-9]+) NOT NULL/TEXT NOT NULL CHECK \(LENGTH\((\1) <= (\2)\)/g' 
sed: -e expression #1, char 87: invalid reference \2 on `s' command's RHS

間違った逆参照を受けています...

理想的には、私は強調する理想的には、NVARCHAR(xy)の後の文字列が次のようなNULL場合いいえ NOT NULL、長さチェックをしたくありません。 NULLの長さを取ることは意味がないためです...これは条件付き動作です。正規表現で可能かどうかはわかりません...

ps。これは些細なことだと思います。

次のデータがあります。

N'Strada Provinciale 1234', N'Reggio Emilia', NULL, N'10289', N'Italy');

単純なアポストロフィ(SQL Serverの場合)N'に変更したいのですが、空の文字列に変更したり、さらに悪く変更したくないので、次のようにします。'N'NULLULL

[pol@fedora data]$ sed 's/N\'\'/g TSQLV5.sql 

しかし得る

sed: -e expression #1, char 7: unterminated `s' command

sed私はそれをたくさん使ってきたことを知っていますが、awk必要なことを行うすべてのコマンドで開いています。

ベストアンサー1

あなたが使用した後fedoraGNU sedこれはうまくいくはずです:

s="  shipname       NVARCHAR(40) NOT NULL,"
echo "$s" | sed -E '/NOT/{s/^  ([[:lower:]]+)\s*NVARCHAR\(([[:digit:]]+)\) NOT NULL,$/\1 TEXT NOT NULL CHECK \(LENGTH\(\1\) <= \2\),/;q0} ; s/^  ([[:lower:]]+)/\1 TEXT NULL,/'

これは偽のifをシミュレートします。

if:

db構造で()を見つけて、NOT最初のsedコマンドを実行し、2番目のステートメントを実行せずに終了()します。/NOT/q0

else:

キーワードが見つからない場合は、NOT2 番目のインスタンスが実行されます。


2番目の要件の場合:

sed "s/N'/'/g"

グローバルN'に検索して'。多くのエスケープ操作を行わなくても、よりきれいにするために'コマンドライン区切り文字に"置き換えることが役に立つと思います。sed


最初のものをsedファイルに入れます。

#!/bin/sed -Ef

# If a NOT is found execute this:
# capture the column name and the value of this
/NOT/ {
    s/^  ([[:lower:]]+)\s*NVARCHAR\(([[:digit:]]+)\) NOT NULL,$/\1 TEXT NOT NULL CHECK \(LENGTH\(\1\) <= \2\),/

    # Quit without execute the other statement
    q0
}

# Else: If we are here then the database
# structure does not contains a length for the column;
# so it should be NULL
s/^  ([[:lower:]]+)/\1 TEXT NULL,/

このコマンドは、より多くのコマンドをグループ化{するために使用されます。sed

終了するコマンドですq。最初のテストが成功した場合は、最後の行に出会う前に強制終了するためにここで使用しています。quitsedsed

おすすめ記事