*がドットファイルと一致するかどうかを制御するためのbashのglobbing設定は何ですか?

*がドットファイルと一致するかどうかを制御するためのbashのglobbing設定は何ですか?

mv ./* ../somedirectory 私は最近似たようなことをしましたが、似たようなファイルが移動されないのを見て.gitignore驚きました。

私の仕事のほとんどはOS Xのzshで行われました。 OS Xでbashを試しましたが、同じ動作を見つけました。*ドットファイルと一致しません。これは私にとって非常に望ましくないようですが、明らかにこれはbashのデフォルトです。 (私が知っている限り、これはzshのデフォルト値かもしれませんが、数年前に.zshrcで変更して動作が異なることを忘れてしまったかもしれません。)

期待どおりに動作するように bash を設定するにはどうすればよいですか? for * はドットファイルを無視せずにすべてのファイルと一致します。

これがまったく明確でない場合、再現方法は次のとおりです。

cd /tmp
mkdir {t,d}est
touch test/{.,}{1,2,3,4,5,6,7}
ls -hal test
mv test/* dest
ls -hal test     # notice dot files are still there
ls -hal dest     # notice only some files were mv'ed

答え1

吹く

すでに知っているように、bashは.名前の先頭のaまたはスラッシュと一致しません。問題の点の一致を変更するには、次のオプションを設定する必要がありますdotglob男乱交:

dotglobを設定すると、bashには「.」で始まるファイル名が含まれます。
    パス名拡張の結果です。

bashを使用して有効/設定するには、shopt次の手順を実行します。

shopt -s dotglob


zshの場合は、このオプションを使用することもできますが、次のように有効にする必要がありdotglobます。setopt

setopt dotglob

答え2

*シェルによって拡張されたグローブです。デフォルトでは、シェルには、先頭の単語を文字通り入力しない限り、名前が.aで始まるファイル(隠しファイルまたはドットファイルと呼ばれる)は含まれていません。.

*または、または、または、ドットファイル[.]*?*含まれません。*.*dir/*

.*それともdir/.*そうでしょう。

だからあなたはこれを行うことができます:

mv -- * .* /dest/

ただし、一部のシェルにはインクルードbash(含まれていないzshmkshなどのバグがある機能、つまりインクルードおよび特殊ディレクトリエントリの拡張機能がありますfish。通常これが私がそれをエラー関数と呼ぶ理由です。).*...

したがって、時には人々が(Bourneのようなシェルで)次のものを使用しているのがわかります。

mv -- * .[!.]* ..?* /dest/

これらは3つのglobで、最初は隠されていないファイルと一致し、2番目のファイル名は.1文字以外の文字で始まり、その後に続き.、3番目のファイル名は次から始まり、少なくとも..1文字が続きます。

ただし、一部の現代のシェルには、この問題を解決するためのより良い方法があります。

扱いにくい

Passを使用すると、glob修飾子を使用してglobにドットファイルを含めることを指定zshできます。(D)

mv -- *(D) /dest/

zshmvまた、パターンが一致しない場合、コマンドが実行されないBourneシェルの追加のバグ機能が修正されました。

上記のように、グローバルアイテムには含まれたり.含まれません。..

mv -- * .* /dest/

安全でしょう。ただし、一致するファイルが存在しない場合、または*一致するファイルが存在しない場合は.*コマンドが中断されるため、次のことをお勧めします。

mv -- (*|.*) /dest/

他のシェルと同様に、すべてのglobにドットファイルを含めることを強制することもできます(たとえば、ドットファイルをより頻繁に含めたい場合)。

setopt dotglob

または:

set -o dotglob

その後、特定のグローブが欲しいならいいえドットファイルを含めるには、次のように書くことができます。

echo *(^D)

または:

echo [^.]*

吹く

残念ながら、bashグローバル修飾子はありません。したがって、ドットファイルの埋め込みはグローバルにのみ有効にできます。のbash構文は次のとおりです。

shopt -s dotglob

(そして[^.]*隠されたファイルがないglobの場合)。

の場合は、dotglobなどのグローバル変数には含まれていませbashんが、そのようなグローバル変数にはまだ適用されます。...*.*

GLOBIGNORE変数をnull以外の値に設定すると、自動的にdotglobオプションが有効になり、globからandは除外されますが、.or(!)は除外されないため、この保護はほとんど役に立ちません。これは可能ですが、orなどのグローバル変数は削除されます。...*dir/.*.*/fileGLOBIGNORE='*/.:*/..:./*:../*:*/./*:*/../*'*/../*../*

より良い解決策は、または[.]*dir/[.]*有効[.]*/file)を使用しておよびを除いてドットファイルをdotglob拡張することです。...

fish.globにはNorは含まれていません..。一致するものがない場合は、バージョンによってzsh(またはbash -o failglob)のように動作しますbash -o nullglob

mv -- * .* /dest/

隠しファイルと非表示ファイルの両方が存在する場合に機能します。それ以外の場合、YMMV および一部のバージョンでは、ファイルmv -- /destがまったくない場合に呼び出されることがあります。

クッシュ 93

両方ともグローバル修飾子はありませんksh93。次のコマンドを使用して、globにドットファイルを含めることができます。

FIGNORE='@(.|..)'

'とはbash対照的に、これは正確で、GLOBIGNOREandを含む問題も解決します。.*...

ヤッシュ

yashdot-globオプション()がありますが、set -o dot-globそれとは対照的に、bashグローバル拡張が(さらに*)含まれているので、.かなり..役に立ちません。

tcsh

set globdot

inに似ていますbash。つまり、and以外のドットファイルも含まれてい*ますが、まだandが含まれます(そしてそれを使用して、and以外の隠しファイルを拡張することができます)。....*...[.]*...

答え3

私はこれをテストし、問題を解決しました。

shopt -s dotglob

出力:

~/stackexchangeanswers/40662$ ls -hal dest
total 8.0K
drwxr-xr-x 2 jodiec jodiec 4.0K 2012-06-12 22:15 .
drwxr-xr-x 4 jodiec jodiec 4.0K 2012-06-12 22:15 ..
-rw-r--r-- 1 jodiec jodiec    0 2012-06-12 22:15 1
-rw-r--r-- 1 jodiec jodiec    0 2012-06-12 22:15 .1
-rw-r--r-- 1 jodiec jodiec    0 2012-06-12 22:15 2
-rw-r--r-- 1 jodiec jodiec    0 2012-06-12 22:15 .2
-rw-r--r-- 1 jodiec jodiec    0 2012-06-12 22:15 3
-rw-r--r-- 1 jodiec jodiec    0 2012-06-12 22:15 .3
...snipped....

答え4

GLOBIGNORE=/+/ @user79743のこの設定に非常に興味があります。

私の経験によると未設定グループは悪いビジネスほぼすべてのコマンド(cp、mvなど)だけでなく、環境nullglob(特にエスケープが必要な正規表現!)

ただし、プログラムの先頭にこれを設定する必要がありますが、cp、mvなどのコマンド呼び出しや正規表現の特定の部分の使用を妨げる場合は、次のようにします。

  # set dotglob, unset nullglob AFTER this
  is_nullglob=$( shopt -s | egrep -i '.*nullglob' )
  is_dotglob=$( shopt -s | egrep -i '.*dotglob' )
  [[ $is_nullglob ]] && shopt -u nullglob
  [[ ! $is_dotglob ]] && shopt -s dotglob
  # ... call commands ...
  # .....................
  # reset dotglob, nullglob to their previous values
  [[ $is_nullglob ]] && shopt -s nullglob
  [[ ! $is_dotglob ]] && shopt -u dotglob

関連情報