2016-11-08 20 views
3

ファイル名から特殊文字を削除し、スペースで置き換えます。私はそこに含まれている単一のバックスラッシュを持つファイルとは別に作業しています。 注これらのファイルはOS X上でFinderでtrでバックスラッシュを削除する

old_name="testing\this\folder" 
new_name=$(echo $old_name | tr '<>:\\#%|?*' ' '); 

を作成しているこれは私がちょうどバックスラッシュではなく、直前の文字を削除するにはどうすればよい 「hisolderをテスト」されているNEW_NAMEになり?以上、shell parameter expansion上のBashマニュアルを参照してくださいについては

$ old_name="testing\this\folder" 
$ new_name=${old_name//[<>:\\#%|?*]/ } 
$ echo $new_name 
testing this folder 

+1

どのように_special characters_を定義するかに応じて、 'tr -d '[:punct:]'' –

答えて

3

"テストhisolder"

\t\fが実際に交換されるので、この文字列は、echo -e "testing\this\folder"の結果のように見えます表形式とフォームフィードの制御文字はです。

たぶん、あなたはalias echo='echo -e'のような別名を持っている、または多分シェルのバージョンでechoの実装は、バックスラッシュはエスケープ解釈:

POSIXは、任意のオプションのサポートを必要としない、との 行動することを言いますSTRINGに バックスラッシュが含まれている場合、または最初の引数が '-n'の場合、 'echo'は実装定義です。移植可能なプログラムは、末尾の改行を省略するか、 制御文字またはバックスラッシュを出力する必要がある場合は、 'printf'コマンドを使用できます。

(情報ページから)

だからあなたは新しいソフトウェアでprintf代わりのechoを使用する必要があります。特にecho $old_nameprintf %s "$old_name"に置き換えてください。

たとえば、this discussionには説明があります。

提案@ mklement0としてprintf

のための必要はありません、あなたはBash here stringによってパイプを避けることはできません。

tr '<>:\\#%|?*' ' ' <<<"$old_name" 
2

はバッシュを使用すると、パラメータ展開を使用することができます。

-1

あなたのテストケースには\のエスケープが正しく行われていないと思うので、実際に文字列に含まれているバックスラッシュの大文字小文字をテストしているわけではありません。

この

は私のために働いた:

old_name='testing\\this\\folder' 
new_name=$(echo $old_name | tr '<>:\\#%|?*' ' '); 
echo $new_name 
# testing this folder 
これがあることNEW_NAMEになり
+0

のようなものを利用することができます。これは 'echo'組み込み関数を使用して、これは2つのバックスラッシュを保存し、結果の文字列は単語間に_2_スペースを持ちます。 (逆に、OPのコードはそのまま動作するはずです。)それ以外にも、 '$ old_name'は二重引用符で囲む必要があります。あなたのエスケープはオプション 'xpg_echo'が(暗黙的にまたは明示的に)有効になっている場合にのみ機能しますが、もっと良い解決策は' printf'またはhere-stringを使うことです。 – mklement0

2

Ruslan's excellent answerは、あなたのコマンドを使用して提供するために働いていないことが理由を説明します堅牢でポータブルなソリューションです。

TLは、DRは:

  • あなたはおそらく(MacOSの上shが変装してバッシュであっても)shではなく、bashでコードを実行したか、シェルオプションxpg_echoが明示的にオンになっていました。
  • echoの代わりにprintfを移植性のために使用してください。 bashで

デフォルトでechoないをしているため、デフォルトのオプションでとecho組み込みを使用して、あなたのコマンドは、(あなたが堅牢性のために二重引用符$old_name必要があることを除いて)として、ある動作するはずですオペランドに\tなどのエスケープシーケンスを展開します。

  • 明示的、暗示的にshopt -s xpg_echo
  • を実行することで、あなたはshとして、または(どの--posixオプションでバッシュを実行する場合:しかし、バッシュのecho制御文字のエスケープシーケンスを拡張させることができる

    、他のオプションや行動の変更の中でも、xpg_echo

あなたのたとえば、シバンライン#!/bin/shでスクリプトからコードを実行すると、ymptomが発生している可能性があります。しかし

、あなたがポータブルスクリプトを書いている場合は、すなわち、shをターゲットにしている場合、その後、echoは、その行動は貝殻やプラットフォーム間で異なることは非常に理由で完全に避けるべきである - ルスランのprintfソリューションを参照してください。明示的にあなたの結果に許可されている文字のみを記載し、-Cオプションで他を除く:

おそらくあなた trコマンドにより堅牢なアプローチが ホワイトリストアプローチです:余談として


old_name='testing\this\folder' 
new_name=$(printf '%s' "$old_name" | tr -C '[:alnum:]_-' ' ') 

このように、文字、数字、_、または-のいずれかでない文字は、スペースで置き換えられます。

+0

徹底的な説明をいただきありがとうございます – rndy

関連する問題