[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]+)
そして代替
TEXT
NOT 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'
NULL
ULL
[pol@fedora data]$ sed 's/N\'\'/g TSQLV5.sql
しかし得る
sed: -e expression #1, char 7: unterminated `s' command
sed
私はそれをたくさん使ってきたことを知っていますが、awk
必要なことを行うすべてのコマンドで開いています。
ベストアンサー1
あなたが使用した後fedora
:GNU 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
:
キーワードが見つからない場合は、NOT
2 番目のインスタンスが実行されます。
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
。最初のテストが成功した場合は、最後の行に出会う前に強制終了するためにここで使用しています。quit
sed
sed