私は基本的な検索/置換で幸運になりました。
find . -name "*.php" -exec sed -i -e "s/<?php include 'http:\/\/www/<?php include '..\//g" \{\} \;
同様の結果を得る方法があるかどうか疑問に思います。しかし、現在のディレクトリの「深さ」を考慮し、構造../
の各レベルの代替文字列の前に追加を追加しますか?
答え1
次のように試すことができます。
find . -name '*.php' -exec sh -c \
'PREFIX=${1//[!/]/}; PREFIX=${PREFIX//\//..\/}; ...' sh {} \;
見つかったファイルが裏面に設定されますPREFIX
。その後、シェル変数を使用してその場所にコマンドを挿入できます。../
dir/filename
sed
...
$PREFIX
これには${var//find/repl}
拡張機能を備えたシェルが必要です。これはPOSIXでは指定されていませんが、Bash
一部のPOSIX実装ではash
指定されています。それ以外の場合は、プレフィックスを実行するには別のものを使用する必要があります。この場合、単一のawk
プロセスを使用してそのセクションでプレフィックス操作を実行し、(別々のプロセスの代わりにBEGIN
)ファイルの各行で置換を実行します。sed
答え2
サイトルートに関連付けられているディレクトリの深さに依存するベースURLを強制的に適用する同様の作業がありました。
完全なソリューションは以下に掲載されています。 @dubiousjimの答えに基づいていますが、引用の問題を避けるために、シェル機能を使用して少し異なるアプローチをとります。
fixlinks() {
# strip the first level depth as we don't need it
BASE=${1/#\.\//}
# leave only one slash char for each nested dir
BASE=${BASE//[!\/]/}
# replace each / with ../ (escaped to ..\/ to be used as sed replacement part)
BASE=${BASE//\//..\\\/}
if [[ $BASE ]]; then
# enable debug mode
set -x
# add <base> tag leading to site root after <head> for each nested file
sed -E -i "s/<head>\r?$/<head><base href=\"$BASE\"\/>/g" "$1"
# silently disable debug mode
{ set +x; } 2>/dev/null
fi
}
# iterate over all files from the site root
find . -name '*.html' | while read file; do fixlinks "$file"; done