2016-08-19 8 views
-1

は私がsedコマンドラインで変数を使う方法は?

# some other configuration settings 
..... 
wrapper.java.classpath.1=/opt/project/services/wrapper.jar 
wrapper.java.classpath.2=/opt/project/RealTimeServer/RTEServer.jar 
wrapper.java.classpath.3=/opt/project/mysql-connector-java-5.1.39-bin.jar 
..... 
# some other configuration settings 

を持って、この設定ファイルを持っていると私はそれがこの

# some other configuration settings 
..... 
wrapper.java.classpath.1=/opt/project/services/wrapper.jar 
wrapper.java.classpath.2=/opt/project/RealTimeServer/RTEServer.jar 
wrapper.java.classpath.3=/opt/project/mysql-connector-java-5.1.39-bin.jar 
wrapper.java.classpath.4=/opt/project/RealTimeServer/some_other.jar 
..... 
# some other configuration settings 

に見えるようにしたいだから、私はこの方法

それを呼び出す

#!/bin/bash 

CONF_FILE=$1 
JAR_FILE=$2 
DIR=$3 

# Get the last wrapper.java.classpath.N=/some_path line 
CLASSPATH=`awk '/classpath/ {aline=$0} END{print aline}' $CONF_FILE` 
echo $CLASSPATH 

# Get the left side of the equation 
IFS='=' read -ra LS <<< "$CLASSPATH" 

# Get the value of N 
NUM=${LS##*\.} 

# Increment by 1 
NUM=$((NUM+1)) 
echo $NUM 

NEW_LINE="wrapper.java.classpath.$NUM=$DIR/$JAR_FILE" 
echo $NEW_LINE 

# Append classpath line to conf file 
sed "/$CLASSPATH/a \\${NEW_LINE}" $CONF_FILE 

このbashシェルを書きました

./append_classpath.sh some_file.conf some_other.jar /opt/project/RealTimeServer 

しかし、私はちょうどあなたのシェルスクリプトを見

sed: -e expression #1, char 28: unknown command: `o' 
+3

巨大でない場合、それは何を問題ないはずですあなたの変数はここにありますか? – heemayl

+1

私達にすべての情報を与えてください。テストファイル、変数、使用しているOSとシェル。 –

+0

暗闇の中でちょうど一発: '$ {some_string}'を試してみてください。 $は変数名の最初の文字しか表示していないようです。 $ {some_line}と同じです。 – steffen

答えて

0

を取得します。シェルは、ツールを呼び出す環境ですが、テキストを操作するツールではありません。テキストを操作する標準の汎用UNIXツールはawkです。あなたのシェルスクリプト全体を以下に減らすことができます:

$ dir="/opt/project/RealTimeServer" 
$ jar_file="some_other.jar" 
$ awk -v new="$dir/$jar_file" 'p~/classpath/ && !/classpath/{match(p,/([^=]+\.)([0-9]+)=/,a); print a[1] (++a[2]) "=" new} {print; p=$0}' file 
# some other configuration settings 
..... 
wrapper.java.classpath.1=/opt/project/services/wrapper.jar 
wrapper.java.classpath.2=/opt/project/RealTimeServer/RTEServer.jar 
wrapper.java.classpath.3=/opt/project/mysql-connector-java-5.1.39-bin.jar 
wrapper.java.classpath.4=/opt/project/RealTimeServer/some_other.jar 
..... 
# some other configuration settings 

上記では、3番目のargとmatch()するためにGNU awkを使用しています。 UNIX環境でテキストを操作する必要がある場合は、Arnold RobbinsのEffective Awk Programming、第4版を読んでください。


は今、戻ってあなたの質問に:

これは何をしようとするための構文は次のとおりです。

sed '/'"$some_string"'/a '"$some_line" "$some_file" 

しかし、それをしないか、あなたが自分自身を非難することがあります秘密の、持ち運びできない、維持不能、タマネギをはがす、エスケープするすべての地獄(Is it possible to escape regex metacharacters reliably with sedを参照)!

sedは、個々の行で単純なサブ置換を行うことだけです。その他の場合は、あなたがしようとしているものを、あなたはawkを使用する必要があります。

awk -v regexp="$some_string" -v line="$some_line" '{print} $0~regexp{print line}' file 

注意があなたのシェル変数を使用すると、正規表現の文脈でそれを使用していた「some_string」と命名されます(SEDで行うことができ、すべての)ので、私はそれを使用していることawkコマンドのregexpコンテキストでもあり、明確にするために "string"ではなく "regexp"というawk変数を付け加えました。

あなたが本当にそれが文字列ではなく、正規表現として扱われたくなかったら、その後それはなるだろう:

awk -v string="$some_string" -v line="$some_line" '{print} index($0,string){print line}' file 

上記の唯一の注意点は、時にawkのシェル変数でバックスラッシュが展開されるということです変数はそれらから初期化されるため、例えば\tはリテラルタブ文字になります。それが望ましくない場合は、私たちに知らせて、バックスラッシュを展開しないawk変数を初期化するための代替構文を提供することができます。http://cfajohnson.com/shell/cus-faq-2.html#Q24を参照してください。

+0

ありがとう、しかし私はこれを試して、行を追加しませんでした。ラッパー行の前後に行があることに注意してください。これを反映するために投稿を編集します。 –

+0

また、一致する一重引用符が間違っていますか? sed '/' "$ some_string" '/ a "" $ some_line "'" $ some_file "のようになります。私は文法を修正した後、それをあまり役に立たないイベントにも使用しました。 –

+0

あなたの実際の入力がサンプル入力のように見えない場合、すべてのベットはオフです。とにかく使用されるべきではないので、sedコマンドの引用符を見落とした可能性があります。実際には1つの見積もりが多すぎます。 –

0

sedコマンドは、変数のスラッシュに問題があります。 な#などいくつかのユニークな区切り文字を探し、

CLASSPATH="wrapper.java.classpath.4=/opt/project/RealTimeServer/some_other.jar" 
NEW_LINE="wrapper.java.classpath.5=your/data.rar" 

echo "# some other configuration settings 
..... 
wrapper.java.classpath.1=/opt/project/services/wrapper.jar 
wrapper.java.classpath.2=/opt/project/RealTimeServer/RTEServer.jar 
wrapper.java.classpath.3=/opt/project/mysql-connector-java-5.1.39-bin.jar 
wrapper.java.classpath.4=/opt/project/RealTimeServer/some_other.jar 
..... 
# some other configuration settings 

Some more config lines 
" | sed "s#${CLASSPATH}#&\n${NEW_LINE}#" 
+0

スラッシュだけではなく文字数に問題がありますが、 BRE regexpメタキャラクタ、バックスラッシュの後に数字、または '&'を付けます。sedを使用してこれを行うには何が必要かについてはhttp://stackoverflow.com/q/29613304/1745001を参照してください。 –

0

ような何かをしようとは、これは、1つのパスの純粋なbashのソリューションです - 設定ファイルが

pfx=wrapper.java.classpath. 
while IFS= read -r line; do 
    if [[ $line == $pfx*=* ]]; then 
    lastclasspath=$line 
    elif [[ -n $lastclasspath ]]; then 
    newline=${lastclasspath#$pfx} 
    num=${newline%%=*} 
    newline="$pfx$((num+1))=$DIR/$JAR_FILE" 
    echo "$newline" 
    unset lastclasspath 
    fi 
    echo "$line" 
done <$CONF_FILE 
関連する問題