中かっこ拡張を使用して、異なる名前のファイルを同じディレクトリにコピーしようとしています。私はbash 4.4.18を使用しています。
これが私がしたことです:
cp ~/some/dir/{my-file-to-rename.bin, new-name-of-file.bin}
ただし、次のエラーが発生します。
cp: cannot stat '/home/xyz/some/dir/{my-file-to-rename.bin,': No such file or directory
このような単純な中括弧拡張にも同じエラーが発生します。
cp {my-file-to-rename.bin, new-name-of-file.bin}
私は何が間違っていましたか?
答え1
これ支柱の拡張構文にはカンマは使用できますが、コンマの後のスペースは使用できません。多くのプログラミング言語では、カンマの後のスペースは一般的ですが、ここではそうではありません。 Bashでは、引用符で囲まれていない空白がある場合、中括弧の拡張は行われません。
スペースを削除してください。
cp ~/some/dir/{my-file-to-rename.bin,new-name-of-file.bin}
完全に不要ですが、末尾を中.bin
かっこの外に移動できます。
cp ~/some/dir/{my-file-to-rename,new-name-of-file}.bin
支柱の拡張効果をテストするには、echo
またはprintf '%s '
、またはを使用できます。printf
これを行うには、目的の書式文字列を使用してください。 (個人的にecho
Bashにいるときにこれを使用する理由は次のとおりです。バッシュecho
内蔵エスケープシーケンスはデフォルトでは拡張されていないため、実行された実際のコマンドを調べるのに理想的です。 )例えば:
ek@Io:~$ echo cp ~/some/dir/{my-file-to-rename,new-name-of-file}.bin
cp /home/ek/some/dir/my-file-to-rename.bin /home/ek/some/dir/new-name-of-file.bin
答え2
string{foo, bar}
中括弧の拡張ではなく、単なるstring{foo,
単語ですbar}
。中かっこ拡張を使用するには、中かっこが同じ単語内になければなりません。必要でない場合は余分なスペースを削除するか、本当に必要な場合は引用符を付ける必要があります。
$ printf "%s\n" aa{bb, cc}
aa{bb,
cc}
$ printf "%s\n" aa{bb,cc}
aabb
aacc
$ printf "%s\n" aa{bb," cc"}
aabb
aa cc
答え3
Bashはこの空間を他の空間と同様に扱います。 IFS として内部フィールド区切り記号です。これは拡張ワード分割に使用され、read組み込みコマンドを使用して行を単語に分割します。
シェルはIFSの各文字を区切り文字として扱い、他の拡張結果をこれらの文字の単語に分割します。 IFSが設定されていない場合、またはその値がデフォルト値の場合、前の拡張結果の始まりと終わりにある、およびシーケンスは無視され、始まりまたは終わりにないIFS文字シーケンスは区切るために使用されます。言葉。 IFSにデフォルト以外の値がある場合、スペース文字がIFS値(IFSスペース)にある限り、単語の先頭と末尾のスペースとタブのシーケンスは無視されます。 IFS スペースではなく、IFS のすべての文字と隣接する IFS スペース文字が一緒にフィールドを区別します。空白文字の IFS シーケンスも区切り文字と見なされます。 IFS値が空の場合、単語分割は発生しません。
-バッシュ(1)
エスケープされていない区切り文字を挿入すると、コマンドと引数が次のようになることをbashに通知できます。
- 「cp」
- "~/some/dir/{名前を変更するファイル.bin"
- 「新しいファイル名.bin}」
引用符またはエスケープ文字 "\"がある場合は、次のようにします。
- 「cp」
- "~/some/dir/{名前を変更するファイル.bin,\新しいファイル名.bin}"
「new-name-of-file.bin」が新しいファイル名でない限り、これは望むものではありません。スペースを含みます。角かっこ拡張が最初に発生し、次にチルダ拡張が発生するため、bashは次のことを行います。
- 「cp」
- "/path/to/home/some/dir/my-file-to-rename.bin"
- "/path/to/home/some/dir/\ 新しいファイル名.bin"
スペースだけを削除すると、すべての問題が解決されます。