背景:
特定の文字列に関連する値を挿入するbashスクリプト(MacOS 10.9.5)を作成したいと思います。スクリプトで可能な各関連値を定義します。
たとえば、リンクテキストに関連するテキストを変数yahoo
として定義できます。www.yahoo.com
XX_yahoo="www.yahoo.com"
XX_
既存の変数との名前の競合を避けるためにプレフィックスが追加されます。それから私のスクリプトは
\MakeLink[yahoo]{}
そして
\MakeLink[yahoo]{www.yahoo.com}
マクロ角かっこ内のリンクテキストを既存の変数と\MakeLink
一致させます。一部のテキストに変数が指定されていない場合は、リンクテキストのタイトルケースを使用します。したがって、
\MakeLink[foo bar]{}
しなければならない
\MakeLink[foo bar]{Foo Bar}
以下のスクリプトは、次の状況を処理します。
- リンクテキストはいいえスペースがあり、
- リンクテキスト変数はまだ定義されていません。
質問:
リンクテキストに可能な値の数は数千になり、その中にスペースがある可能性があるため、私の質問は次のとおりです。
- これが最善の方法ですか?配列を変数として使用する方が良いでしょうか?
リンクテキストにスペースがある場合はどうすればよいですか?たとえば、私は
\MakeLink[the google]{}
に置き換えられます
\MakeLink[the google]{www.google.com}.
ノート
- あると推測できる。ただ
\MakeLink
1行に1回表示されます。 MakeTitleCase
タイトルなど、大文字と小文字が変更されない単語のリストを持つようにマクロを改善する必要がありますが、後で変更できます。
既存のソリューションの既知の問題:
\MakeLink
前にバックスラッシュを省略しても一致が引き続き発生するため、一致する方法に問題があります。テストケースの最初の段落の最後の行を参照してください。- 私のファイル
?
に1つがあると、何かがsed
間違っているようです。 - リンクテキストにスペースが含まれている場合をどのように処理するのかわかりません。
スクリプト
#!/bin/bash
## Can't have a backslash in the values of these variables, which is ok for my purposes.
XX_yahoo="www.yahoo.com"
XX_google="www.google.com"
function MakeTitleCase {
echo $(echo "$1" | awk '{for(j=1;j<=NF;j++){ $j=toupper(substr($j,1,1)) substr($j,2) }}1')
}
while read -d $'\n' LINE; do
## Extract target which is the text within the square brackets of "\MakeLink[target]{}"
TARGET=$(echo ${LINE} | sed -e 's?\]{}.*??' -e 's?\MakeLink\[??')
TEMP=XX_${TARGET}
if [ -z "${!TEMP}" ]; then
REPLACEMENT=$(MakeTitleCase "${TARGET}")
else
REPLACEMENT=${!TEMP}
fi
## Incorrect handling of leading backslash for the match.
echo "${LINE}" | sed "s?\MakeLink\[${TARGET}\]{}?\\\MakeLink\[${TARGET}\]{${REPLACEMENT}}?";
done
exit 0
入力ファイルの例:
A very popular site on the internet was
\MakeLink[yahoo]{} but was surpassed by
\MakeLink[google]{} due to its
MakeLink[search engine]{}.
Due to its dominance
\MakeLink[the google]{} has had to deal with
\MakeLink[antitrust issues]{}.
現在の出力:
A very popular site on the internet was
\MakeLink[yahoo]{www.yahoo.com} but was surpassed by
\MakeLink[google]{www.google.com} due to its
\MakeLink[search engine]{Search Engine}.
Due to its dominance
\MakeLink[the google]{The Google} has had to deal with
\MakeLink[antitrust issues]{Antitrust Issues}.
希望の出力:
上記の唯一の変更は関連テキストthe google
です。MakeLink[search engine]{}
いいえ先行バックスラッシュが欠落して変更されました。
A very popular site on the internet was
\MakeLink[yahoo]{www.yahoo.com} but was surpassed by
\MakeLink[google]{www.google.com} due to its
MakeLink[search engine]{}.
Due to its dominance
\MakeLink[the google]{www.google.com} has had to deal with
\MakeLink[antitrust issues]{Antitrust Issues}.
ベストアンサー1
Perlが構造に来ます:
#!/usr/bin/perl
use warnings;
use strict;
my %replace = ( yahoo => 'www.yahoo.com',
google => 'www.google.com',
'search engine' => 'Search Engine',
'the google' => 'The Google',
'antitrust issues' => 'Antitrust Issues',
);
while (<>) {
s/\\MakeLink\[(.*?)\]\{\}/\\MakeLink[$1]{$replace{$1}}/g;
print;
}
代替ハッシュテーブルを作成し、それを置換に使用します。最新のbashバージョンではハッシュテーブルを作成できますが、sedでは直接使用できないため、直接bash + sed対応エントリはありません。