特定のディレクトリ内のすべてのファイルを繰り返し収集

特定のディレクトリ内のすべてのファイルを繰り返し収集

拡張子を持つ多くのディレクトリを持つプロジェクトがあります.strings

これらのファイルは複数の言語でローカライズされたバージョンです。

たとえば、同じ名前のファイルが3つありますが、各ファイルは、またはMyView.stringsなどのローカライズされたディレクトリにあります。プロジェクト構造には、これらのディレクトリが何百ものあります。en.lprojit.lprojpt-PT.lproj

私はこれらのすべてのファイルを含むディレクトリを言語別にリストするbashスクリプトを作成しています。

en.lproj例:ディレクトリ構造をスキャンし、その構造に存在する可能性のあるすべてのディレクトリを見つけ、そのディレクトリ内のすべてのファイルのフルパスを一覧表示したいと思います。

その問題に対して、このようなコマンドは端末ウィンドウで機能します

find . -type d -name "en.lproj" -print  

しかし、後でbashスクリプトで列挙するためにそのようなコマンドの結果を配列に保存する方法は何ですか?

私はこれを試しました

result=($(find . -type d -name "en.lproj" -print))

ただし、パスにスペースが含まれているため、そのスペース内の配列が破損し、結果が空白の有無にかかわらず、各行がパスである配列になると予想されます。

私はmacOS BigSurを使用しています。

答え1

コマンドの出力を配列として保存するには、次のものが必要です。

array=( $(command) )

ただし、シェルは値に基づいてコマンドの結果を分割します$IFS。これは通常空白、タブ、および改行に設定されるため、これらの文字を含むファイル名を返すコマンドを使用すると、配列は名前の各部分に別々の要素を持ちます。表示するには:

$ touch 'a file with spaces'
$ ls
'a file with spaces'

$ array=( $( find . -type f) )

$ for f in "${array[@]}"; do echo "FF: $f"; done
FF: ./a
FF: file
FF: with
FF: spaces

あなたの場合、すべてのファイルに空白のない単純な名前がある場合は、次のことができます(必須ではなく、-printこれは基本的な作業です)。

files=( $(find . -type d -name "en.lproj") )

ただし、安全のために$IFSこのコマンドをオーバーライドして、すべてのファイル名に対して機能させることができます(改行を含むファイル名を除く)。

$ IFS=$'\n' array=( $( find . -type f) )
$ for f in "${array[@]}"; do echo "FF: $f"; done
FF: ./a file with spaces

改行文字を含む任意のファイル名を処理できる必要がある場合は、区切り文字を使用してnullに設定することもできます(移植可能ではありませんが、GNUおよびBSDでサポートされているため、Mac上で作業する必要があります)mapfilefind)改行の代わりに空の区切り文字を使用して結果を印刷するオプション-print0find

mapfile -d '' array < <(find . -type f -print0)

これはあらゆる種類のファイルを処理します。

$ touch 'a bad
file'
$ ls
'a bad'$'\n''file'  'a file with spaces'

$ mapfile -d '' array < <(find . -type f -print0)
$ for f in "${array[@]}"; do echo "FF: $f"; done
FF: ./a file with spaces
FF: ./a bad
file

関連情報