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