sed を使用して (***) を \(***\) に置き換える方法

sed を使用して (***) を \(***\) に置き換える方法

そこで、mkdirコマンドに渡すことができるように、特殊文字をエスケープされたその文字に置き換えるスクリプトを作成したいと思います。友だちが同様の行を使用しているため、これを使用して角かっこを次の下線に置き換えることができます。

echo 'Hello (World)' | sed 's/(\|)/_/g'

しかし、次のコマンドに変更すると、出力は私が望むものではありません。

echo 'Hello (World)' | sed 's/(\|)/\(\|\)/g'

システム出力: Hello (|)World(|)
希望の出力: Hello \(World\)

これを行う方法はありますか? "tr"コマンドを使用するなど、他の人の提案を使用しましたが、それからも目的の出力を取得できませんでした。

答え1

... mkdirコマンドに渡すためにエスケープされた対応するエントリを使用します。

まったくしないでください。代わりに、引用するひも:

name1="Hello (World)!"
name2="I want this to be a five-star directory (*****)"
mkdir -- "${name1}" "${name2}"

そうでなければ

mkdir "Hello (World)"
mkdir "I want this to be a five-star directory (*****)"

シンプルで効果的です。

答え2

私は以下をお勧めします:

1. やや読みやすいバージョン

echo 'Hello (World)' | sed 's/(/\\(/g' | sed 's/)/\\)/g'

各呼び出しは、ブラケットタイプに対するものです。 「検索」部分は角括弧のみを探し、置換部分は同じ角括弧を再配置しますが、バックスラッシュの後にエスケープする必要があります。

2. コンパクト

これはまた働きます:

echo 'Hello (World)' | sed -E 's/(\(|\))/\\\1/g'

ここでは sed を一度だけ呼び出します。

-E括弧と特殊文字に関して異なる動作をする(そしてさらに「現代的な」)拡張正規表現を使用するようにsedに指示します。これにより、キャプチャグループを使用できます。

「検索」セクションでは、sedに開き括弧または閉じ括弧を見つけるように指示します。彼らは脱出した。完全な「(または)」グループ自体は括弧で囲まれています。この括弧は、グループに見つかった内容を記憶するようにsedに指示するために使用されるため、エスケープされません。次に、交換部分にバックスラッシュ(以前のようにエスケープされた)を置き、sedが以前に見つけたものを\1

3. mkdirに接続

問題の鍵は、sed 実装で提供される出力です。 OPが簡単に言及した元の意図に関しては、このアプローチは少し人為的ですが、うまくいきます。 「Hello(World)」というディレクトリの場合、次のように動作します。

echo 'Hello (World)' | sed 's/(/\\(/g' | sed 's/)/\\)/g' | sed 's/ /\\ /g' | xargs mkdir

私たちも以前のようにこの空間から脱出しなければならない。 Xargs は、前のコマンドの出力を mkdir に渡すために使用されます。または:

echo 'Hello (World)' | sed 's/(/\\(/g' | sed 's/)/\\)/g' | xargs -I{} mkdir '{}'

これにより、前の出力を引用符で囲んでスペースをエスケープするのを防ぐことができます(必要な名前に引用符を含めないことをお勧めします!)。

言及したように、これは非常に設計されています。 mkdirを使用し、単に名前を引用符で囲むもう1つの答えは、OPのアプローチです。

関連情報