bashのcmd "for"と同じですか?

bashのcmd "for"と同じですか?

私はbash(またはLinuxシェル)についてほとんど知りませんが、bashだけを使用します。私はWindowsでcmdを使用することに慣れており、for %c in (*.*) do {something}cmdがなければ不快だと感じます。私はwine cmdを試しましたが、私が望むものではないLinuxコマンドをまったく解釈しません({something}が必要です)。助けが必要ですか?

Windowsでは、ファイルごとに1回for %c in (*.*) do {something}実行されます{something}(ディレクトリは無視されます)。現在の繰り返しのファイル名{something}を参照できます%c。他の修飾子はファイルパスの抽出を許可するか、パスなしでファイル名、ファイル拡張子、属性、変更日時、サイズなどを使用してファイルの代わりにディレクトリをfor /d %c in (*.*) ...処理します。どちらの場合も、Unixスタイルのシステム*.*と同じ名前のないファイルやディレクトリを含む、隠されていないすべてのファイルまたはディレクトリと一致します。*.

PS cmd "for"には、bashの1つのコマンドで扱わない可能性がある多くの用途があることを知っていますが、上記のコマンドと同等のものを知りたいです。

答え1

for file in *; do
  echo "$file"
done

ただし、これは通常、「隠し」ファイル(ドットで始まる名前)と一致しません。

隠しファイルを一致させるには、以前もこれを行う必要がありました。

shopt -s dotglob

ディレクトリ(およびおそらく「奇妙な」エントリ)をスキップするには、ループ内でそのディレクトリを検索する必要があります。パターンマッチング(*)はオブジェクトタイプには気にしません。

for file in *; do
  test -f "$file" || continue
  echo "$file"
done

シンボリックリンクは特別なケースです。ファイルに接続されているがファイルが別のディレクトリにある可能性がある場合に考慮されます。シンボリックリンクを無視します。

for file in *; do
  test -f "$file" || continue
  test -L "$file" && continue
  echo "$file"
done

答え2

説明するパターンマッチングの動作は次のとおりです。技術ネットワークブログ- 古いバグ:


*.*...また、それ自体が同じであることがわかります。*

また、...と入力すると、コマンドプロンプトが入力したように動作しますDIR .TXTDIR *.TXTWindows 95でバグを修正したとき、複数の人が自分のDIR .TXTコマンドが機能しないと文句を言いました。

これFCバルセロナ変換中に一致アルゴリズムが中断されました。Win32長いファイル名では動作しないからです。長いファイル名には複数のドットを含めることができます。もちろん、ファイルは11文字を超えることができ、ドットの前には8文字を超える文字が続くことがあります。しかし、いくつかの珍しいことがあります。FCバルセロナ一致アルゴリズムは、次になるまで続く。Win32慣用語になったからです。

たとえば、パターンがで終わると無視さ.*れます.*。この規則がないと、パターンはドットを含むファイルのみと一致し、Windows NT 3.1を実行しているすべての人が平均的な作業をしている*.*ため、地球上のすべてのバッチファイルの90%とすべての人の筋肉メモリが破損する可能性があります。ファイルの世界 。*.*

別の例として、ドットで終わるパターンは実際にドットで終わるファイルと一致せず、拡張子のないファイルと一致します。疑問符が点の直前にある場合は、ゼロ文字が一致する可能性があります。


これはおそらくUnixの先例の起源と大きく変わらないでしょう。指す次のファイルロブパイク彼のブログからのメモ:


昔からデザイナーとしてUnixファイルシステムが開発中で、ナビゲーションをより簡単にするためにアイテムと.形状が作成されました。..わかりませんが、..バージョン2の再構築中にファイルシステムが階層化されたとき(初期構造は非常に異なっていました)。ただし、と入力するとlsこれらのファイルが表示されるため、KenまたはDennisはプログラムに簡単なテストを追加します。当時はアセンブラで書かれていましたが、問題のコードは次のとおりです。

if (name[0] == '.') continue;

文は予想より少し短いです。

if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) continue;

...しかし、まあ、簡単です...

私は隠されたファイルの概念が意図しない結果であると確信しています。これは確かに間違いです。

(ドットファイルに何らかの目的があると反対する人については、私はそれを否定しませんが、名前の習慣ではなくその目的を提供するファイルであることに反論しています$HOME/cfg$HOME/lib計画9、ドットファイルがありません。教訓を得ることができます。 )


しかし、その時点から、.ドットファイルは.標準のシェルユーティリティに関連付けられ始め、そこではユーザー固有のプレーンテキスト設定ファイルにのみリンクされていました。

君は普通は分からないんだ指すファイルは、ユーザーを除く任意の場所に配置できます。~なぜならそれが実際に意味のある唯一の場所だからです。とにかく、ユーザーはファイルシステムの他の場所にファイルを保存しないでください。ホームディレクトリ内のファイルで作業しているときに、ユーザーが誤って設定ファイルの一部または全部を削除した場合、不幸になる可能性があります。ただし、ホームディレクトリ~または他のディレクトリでループが誤って影響を受けたり、.現在のディレクトリにある場合は、さらに不幸です。(もっと悪い) ..- 親ディレクトリ。 POSIXは私が言いたいことは.:


ファイル名がピリオドで始まる場合は、.ピリオドをパターンの最初の文字として使用するか、スラッシュ文字の直後にピリオドを明示的/に一致させる必要があります。先行期間は次のものと一致しないでください。

  1. アスタリスク*または?疑問符の特殊文字

  2. 角かっこ式(例)、[範囲式(例)、または文字クラス式(例:][!a]"[%-0]"[[:punct:]]

    • たとえば、角かっこ式一致リストの明示的なピリオドが[.abc]ファイル名の前のピリオドと一致できるかどうかは指定されません。

しかし、現在のディレクトリ内のすべてのファイルを繰り返すことはまだ可能です。指すファイルかどうか - ループで十分です。たとえば、

set -- .* *
while until [ -f "$1" ] ||
            [ -z "$1" ] &&
            break "$((!$#+1))"
      do    shift;   done
do    printf %s\\n  "$1"
      shift
done

上記のコマンドは、現在のディレクトリ、、、、、dashおよびのすべての一般ファイルを印刷します。永続シェル変数を設定しないという点で、通常のシェルよりもWindowsループに似ています。引数を処理するのと同じように、処理が完了すると、その名前にはもう値がありません。一般的なシェルでは、inの最後の値はまだ保持されます。bashkshzshmkshposhyashFORforcmd FORfor$varfor var in ...

しかし、実際にはそうではありません。持つそう:

set -- .* * ''
while [ -n "$1" ]  || ! shift
do    [ -f "$1" ]  &&
      set -- "$@" "$1"
      shift
done
printf %s\\n "$@"

...移植的な方法で同じ目標を達成します。つまり、現在のディレクトリのすべての一般的なファイルを印刷します。しかし、まず引数を一度繰り返し、非正規ファイルを切り取ります。しかし、利点は、後でシェルのarg"$@"配列がまだ完全なリストを保持しており、その時点から次のことができることです。

for f do : something w/ "$f"; done

...同じアレイで複数回使用できます。ただし、数を取得して"$#"すべてのパラメータを単一の文字列に連結することもでき、各パラメータはソートされた順序"$*"で個別に処理できます"$1""${10}"

これは通常Win32では実行できない操作ですcmd

答え3

forループ学習に興味があれば

構文 -

for i in $(command with iterable elements); do command $i; done

良い -

for i in $(echo 1 2 3 4 5); do echo $i; done

検索コマンドに興味がある場合 -

find . -name "*"

深さレベル -

find . -maxdepth 1 -name "*"
find . -maxdepth 2 -name "*"

たぶんあなたにもっと役立つかもしれません

関連情報