あなたが探しているのは...sed
行ごとに置換を行うストリーム編集ツールだと思います。
あなたが説明しているように、コマンド `cat named.local | grep zone' を実行すると、次のような出力が得られます。
zone "domain1.tld" {
zone "domain2.tld" {
zone "domain3.tld" {
zone "domain4.tld" {
二重引用符で囲まれたテキストが必要だと言ったので、出力を次のようにしたいと思います。
"domain1.tld"
"domain2.tld"
"domain3.tld"
"domain4.tld"
したがって、実際には、各行から、二重引用符で囲まれたテキスト (二重引用符自体を含む) が必要です。
あなたが正規表現に精通しているかどうかはわかりませんが、正規表現はシェル スクリプトを作成する人にとって非常に貴重なツールです。たとえば、正規表現/.o.e/
は、2 番目の文字が小文字でo
4番目の文字が である単語がある行に一致しますe
。zone
これは、" "、" tone
"、さらには " "I am tone-deaf.
などの単語を含む文字列に一致します。
そこでのトリックは、.
(ドット) 文字を使用して「任意の文字」を意味することでした。*
「前の文字を 0 回以上繰り返す」など、他にもいくつかの特殊文字があります。したがって、次のような正規表現は、" "、" "、または空の文字列にa*
一致します: ""a
aaaaaaa
したがって、次を使用して引用符内の文字列を一致させることができます。/".*"/
あなたが知っている別のことがありますsed
(そして、コメントによって、あなたはすでに知っています!) -バックトラックが可能です。単語の認識方法を指定したら、その単語を置換の一部として使用させることができます。たとえば、このリストを次のように変更したいとします。
Billy "The Kid" Smith
Jimmy "The Fish" Stuart
Chuck "The Man" Norris
このリストに:
The Kid
The Fish
The Man
まず、引用符内の文字列を探します。私たちはすでにそれを見ました、それは/".*"/
.
次に、引用符内にあるものを使用します。括弧を使用してグループ化できます。/"(.*)"/
テキストをアンダースコア付きの引用符に置き換えたい場合は、 replace: を実行するs/"(.*)"/_/
と、次のようになります。
Billy _ Smith
Jimmy _ Stuart
Chuck _ Norris
しかし、後戻りがあります。これにより、記号を使用して、括弧内に何があったかを思い出すことができます\1
。したがって、今実行すると、次s/"(.*)"/\1/
のようになります。
Billy The Kid Smith
Jimmy The Fish Stuart
Chuck The Man Norris
引用符は括弧内にないため、\1
!の内容の一部ではありませんでした。
二重引用符内のものだけを残すには、行全体を一致させる必要があります。そのために、^
(「行頭」を意味する) と$
(「行末」を意味する) があります。
したがって、 を使用するs/^.*"(.*)".*$/\1/
と、次のようになります。
The Kid
The Fish
The Man
なんで?s/^.*"(.*)".*$/\1/
正規表現を左から右に読んでみましょう。
平易な英語では、「行全体を読み、二重引用符の間のテキストを横にコピーします。次に、行全体を二重引用符の間の内容に置き換えます。」
置換するテキストを二重引用符で囲むこともできるs/^.*"(.*)".*$/"\1"/
ため、次のようになります。
"The Kid"
"The Fish"
"The Man"
これを使用しsed
て、行を引用符内のコンテンツに置き換えることができます。
sed -e "s/^.*\"\(.*\)\".*$/\"\1\"/"
(これは、二重引用符やスラッシュなどを処理するためにシェルエスケープされているだけです。)
したがって、コマンド全体は次のようになります。
cat named.local | grep zone | sed -e "s/^.*\"\(.*\)\".*$/\"\1\"/"