問題の説明

問題の説明

SASプログラムでLIBNAMEステートメントを置き換えようとしています。修正したい行の例は次のとおりです。

LIBNAME somelib '/random/path/reference/';

somelib文字列をそのままにして、'/random/path/reference/'私が定義した変数にのみ置き換えたい/some/fake/path/(例:一重引用符で囲む)。

交換しようとすると、sed次のエラーが発生します。

sed: 0602-404 Function s/\(libname[[:space:]]\{1,\}[[:alnum:]]\{1,\}[[:space:]]\{1,\}\)\("([^"]|\\")*"\)/\2\"/some/fake/path/"/ cannot be parsed.

解析できないコードは基本的に次のようになります。

test_path=/some/fake/path/

sed 's/\(libname[[:space:]]\{1,\}[[:alnum:]]\{1,\}[[:space:]]\{1,\}\)\("([^"]|\\")*"\)/\2\"'$test_path'"/I'

私は今何をするのか分からない。

答え1

あなたが投稿した元のスクリプト(現在編集済み)から:

正規表現が4つあるのはなぜですか? (第三に、reg3はエラー行に報告されたものと同じsed正規表現であるようです):

reg1='libname[[:space:]]\{1,\}[[:alnum:]]\{1,\}\.[[:alnum:]]\{1,\}[[:space:]]\{1,\}oracle path'
reg2='libname[[:space:]]\{1,\}'
reg3='\(libname[[:space:]]\{1,\}[[:alnum:]]\{1,\}[[:space:]]\{1,\}\)\("([^"]|\\")*"\)'
sed1='s/\(libname[[:space:]]\{1,\}[[:alnum:]]\{1,\}[[:space:]]\{1,\}\)\("([^"]|\\")*"\)/\2"/some/fake/path/"/I`

問題の説明

全体的な問題は、次のコードに折りたたむことができます。

sourcepath='/random/path/reference/'
test_path='/some/fake/path/'

echo "LIBNAME somelib \"$sourcepath\"" | 
    sed -n 's@\(LIBNAME[[:space:]]\{1,\}[[:alnum:]]\{1,\}[[:space:]]\{1,\}\)\("\(\([^"]\|\\"\)*\)"\)@\1"'"$test_path"'"@p'

印刷されますLIBNAME somelib "/some/fake/path/"

正規表現が一致しない場合は何も印刷されません。

ソリューションスクリプト

その結果、次のスクリプトが作成されました。

#!/bin/ksh -
test_path=/some/fake/path/

reg1='libname[[:space:]]\{1,\}[[:alnum:]]\{1,\}.[[:alnum:]]\{1,\}[[:space:]]\{1,\}oracle path'
reg2='\(LIBNAME[[:space:]]\{1,\}[[:alnum:]]\{1,\}[[:space:]]\{1,\}\)\("\(\([^"]\|\\"\)*\)"\)'
:>./edited.sas

while IFS=$' \t\n' read -r line; do
    newline=$(echo "$line" | sed -n 's@'"$reg2"'@\1"'"$test_path"'"@p')
    if [ -n "$newline" ]; then
        line=$newline
    fi
    echo "$line" 
done < ./original.sas  >> ./edited.sas

より簡単な解決策ですが、まだ...

推奨スクリプト

しかし、シェルはファイルを編集する最良の方法ではありません。
スクリプト全体がsed正規表現に縮小されました。

スクリプトをより簡単に簡素化する必要があります。

#!/bin/ksh

test_path=/some/fake/path/

reg1='\(LIBNAME[[:space:]]\{1,\}[[:alnum:]]\{1,\}[[:space:]]\{1,\}\)\("\(\([^"]\|\\"\)*\)"\)'

sed 's@'"$reg1"'@\1"'"$test_path"'"@' ./original.sas  > ./edited.sas

コードの問題
コードにはいくつかの問題があります。

  1. 一重引用符を使用して変更する必要があると主張しますLIBNAME somelib '/random/path/reference/';。しかし、あなたのコード(正規表現)は二重引用符を一致させようとします。LIBNAME somelib "/random/path/reference/"; どれですか?
  2. 変数の引用がecho $line間違っています。使用: echo "$line"
  3. 変更された値は$line一度だけ印刷されます。
  4. 1つしかないので、echo "$line"ループ全体でこれを行うことをお勧めします。
  5. ;配置のためdo
  6. 最初の正規表現にドットがあるのはなぜですか?必要なポイントを合わせてみてください\.
  7. あなたはできますいいえs///テキストを含めるにはを使用します/s@@@たとえば、使用します。
  8. I()フラグを使用するときはs///IGNU sedを使用する必要がありますか?
  9. sed BREには代替はありません|。 GNU sedとしてのみ使用できます\|
  10. 正規表現の数を最小限にしてください。各正規表現は誤解の原因となる可能性があります。
  11. 新しい変数は、正規表現と一致する場合は行の変更された値に設定できます。変数が空の場合、正規表現は一致しません。

関連情報