入力ファイルのパスを変更しようとしています。
#include "../../../Plumed.h" #### this is old patch in input
#include "/usr/local/include/Plumed.h #### this should be the new path
以前に回答した質問を見た後(https://stackoverflow.com/questions/11245144/replace-whole-line- Contains-a-string-using-sed)。
私はこれを試しました。
sed -i '/../../../Plumed.h/c\/usr/local/include/Plumed.h' ../dist0.xvg
perl -i -pe 's/../../../Plumed.h/usr/local/include/Plumed.h/g' ../dist0.xvg
私はsed / perlが混乱していると思いますが、この問題を克服する方法がわかりません。どんな助けでも大変感謝します。
答え1
TL、博士:
使用:
sed -i 's:"\.\./\.\./\.\./Plumed\.h":"/usr/local/include/Plumed.h":g' ../dist0.xvg
試したSedコマンドに関するいくつかのコメント:
sed -i '/../../../Plumed.h/c\/usr/local/include/Plumed.h' ../dist0.xvg
-i
移植性がないのでGNU Sedを使っているようです。BSD Sed
-i
にもスイッチがありますが、バックアップ拡張子は必須パラメータであるため、BSD Sedにバックアップを保存せずにファイルを変更する必要があります-i ''
。-i
他のバージョンのSedにはスイッチがまったくない場合があります。ここの正規表現には、正規表現の区切り文字
/../../../Plumed.h/
の複数のコピーが含まれています。一般的な解決策は、区切り文字をエスケープすることです。
/..\/..\/..\/Plumed.h/
しかし、Sedについては知られている事実はほとんどありません。どの
s
バックスラッシュで最初のインスタンスをエスケープすると、正規表現の区切り記号です(コマンドだけでなく)。 (ほとんどすべて - バックスラッシュや改行文字は許可されていません。)引用するPOSIX仕様まっすぐ:
コンテキストアドレスで "
\cBREc
"を設定します。氏は<backslash>
、またはを除くすべての文字で、<newline>
「」と同じでなければなりません/BRE/
。指定された文字の場合氏後に表示される文字<backslash>
は、BREを終了しないリテラル文字として扱われます。たとえば、コンテキストアドレス "\xabc\xdefx
"X自分を表しているので、BREは"abcxdef
"です。したがって、「傾いたつまようじ症候群」を防ぐために、次の2つの正規表現が同じであることに注意してください。
/..\/..\/..\/Plumed.h/ \:../../../Plumed.h:
私が「同等だ」と言ったことに注意してくださいいいえ正しい。これは他の答えが見逃してからポイントにつながります。
正規表現のピリオド( )は次のように
.
なります。すべての文字。リテラルピリオドのみを一致させるには、バックスラッシュを使用してピリオドをエスケープするか、 のように文字クラスに貼り付けることができます
[.]
。したがって、リテラルピリオドのみを一致させるには、正規表現は実際には次のようになります。
\:\.\./\.\./\.\./Plumed\.h:
つまようじが傾くのを防ぐためにはあまりにも多くです。
おそらく、より読みやすい形式を使用することもできます。
\:[.][.]/[.][.]/[.][.]/Plumed[.]h:
コマンド
c
が変更されました。ワイヤー、正規表現に一致する行部分だけではありません。s
行の一部のみを変更するには、このコマンドを使用します。s
このコマンドを使用すると、アドレスに代替区切り文字を使用するときと同じように、最初の正規表現区切り記号(区切り文字として使用される珍しい文字の場合でも)をエスケープする必要がないことに注意する価値があります。また、この
c
コマンドに関して同じ行に新しいテキストを含めることはc\
GNU拡張であり、移植性がないことに注目する価値があります。
s
これらすべてをまとめると、次のコマンドを使用できます。
sed -i 's:"\.\./\.\./\.\./Plumed\.h":"/usr/local/include/Plumed.h":g' ../dist0.xvg
あるいは、より明確にしたい場合は、アンカー正規表現とc
hangeコマンドを使用して行全体を変更できます。
sed -i '\:^#include "\.\./\.\./\.\./Plumed\.h"$:c\#include "/usr/local/include/Plumed.h"' ../dist0.xvg
答え2
/
区切り文字として使用する場合、sed
解決策は次のとおりです。
sed -i 's/..\/..\/..\/Plumed.h/\/usr\/local\/include\/Plumed.h/g' file
または とは異なる区切り記号を使用できます。/
たとえば、次のようになります。:
sed -i 's:../../../Plumed.h:/usr/local/include/Plumed.h:g' file
別の方法awk
:
awk '{ gsub("../../../Plumed.h","/usr/local/include/Plumed.h"); print $0}' file
答え3
このコマンドは私にとって効果的です。
sed -i 's#include "../../../Plumed.h"#include "/usr/local/include/Plumed.h"#g'
答え4
テキストにスラッシュが多い場合は感嘆符を使用してください。
sed -e 's!../../../Plumed.h!/usr/local/include/Plumed.h!'