sed +特定の行を一致させた後に複雑な行を追加する方法

sed +特定の行を一致させた後に複雑な行を追加する方法

- で始まる行と一致する行の後にsedを追加したいと思います。次のような複雑な行です。number_of_cars_are

more /tmp/orig_file

number_of_cars_are=$number_of_cars_are

追加したい行は次のとおりです。

numbers=` su hdfs -c "hdfs dfs -ls  $var/*.jar" |sed s'/\// /g' | awk '{print $NF}' | wc -m `

だから私たちは次のことをしました。

sed '/^[[:space:]]*number_of_cars_are =.*/a numbers=` su hdfs -c "hdfs dfs -ls  $var/*.jar" |sed s'/\// /g' | awk '{print $NF}' | wc -m `' /tmp/orig_file > /tmp/new_file

しかし、我々は次のような結果を得る

sed: can't read /g | awk {print: No such file or directory
sed: can't read } | wc -m `: No such file or directory

それで私たちはバックスラッシュも追加してみました。

sed '/^[[:space:]]*number_of_cars_are =.*/a numbers=` su hdfs -c \"hdfs dfs -ls  $var/*.jar\" |sed s'/\// /g' | awk '{print \$NF}' | wc -m `' /tmp/orig_file > /tmp/new_file

しかし、同じように

sed: can't read /g | awk {print: No such file or directory
sed: can't read $NF} | wc -m `: No such file or directory

行を追加する方法に関する提案

答え1

シェルが追加の行の(必要な)特殊シンボルを解釈しないように、Sedコマンドをファイルに配置するのが最善です。

longline.sed:

/^[[:space:]]*number_of_cars_are=/a\
numbers=` su hdfs -c "hdfs dfs -ls  $var/*.jar" |sed s'/\\// /g' | awk '{print $NF}' | wc -m `

Sedはエスケープ文字を解釈するので、唯一の修正はバックスラッシュをエスケープすることです。

$ sed -f longline.sed newfile
more /tmp/orig_file

number_of_cars_are=$number_of_cars_are
numbers=` su hdfs -c "hdfs dfs -ls  $var/*.jar" |sed s'/\// /g' | awk '{print $NF}' | wc -m `

答え2

heredoc <<このシナリオでは、この機能を最大限に活用できます。

repl=$(cat - <<\eof |\
sed -e 's:[\&/]:\\&:g'
numbers=` su hdfs -c "hdfs dfs -ls  $var/*.jar" |sed s'/\// /g' | awk '{print $NF}' | wc -m `
eof
)
$ sed \
    -e '/^[[:blank:]]*number_of_cars_are=/G' \
    -e "s/\\n/&$repl/" \
 /tmp/orig_file 

最初のステップとして、Heredocを使用して追加する行を印刷し、それを処理してRHS s //文字をエスケープし、それをrepl変数に保存します。

次に、選択した行の s///rhs 部分に挿入します。

この方法は非常にPosixlyであり、ファイルは必要ありません。単線形 repl を想定します。

答え3

主な問題は、一重引用符で囲まれた文字列に一重引用符を含めることができないことです。コマンドラインに挿入された行を提供するには、単一引用符文字列を破棄し、引用符で囲まれた単一引用符を追加してから文字列を続行する必要があります。したがって、各単一引用符はまたは'\''で書かれます'"'"'。ここで、隣の2つの一重引用符は、それぞれ一重引用符の前と後に一重引用符文字列で終わって開始されます。

追加の予防措置を講じたくない場合は、文書に挿入する行をテキストとして提供できます。

〜のようにクワジモドの答えただし、ここで参照されているドキュメントを使用すると、コマンドラインから直接可能です。

sed -f /dev/stdin file <<'END_SED'
/^number_of_cars_are/a\
numbers=` su hdfs -c "hdfs dfs -ls  $var/*.jar" |sed s'/\// /g' | awk '{print $NF}' | wc -m `
END_SED

ドキュメントがここに引用されているので(END_SED最初の区切り文字の周りに一重引用符で示されている)、シェルはその中のどの拡張も拡張しません。

このsedユーティリティはこの文書を使用して標準入力から読み取られます-f /dev/stdin

関連情報