我有一个项目,有很多目录,其中包含扩展名为.strings
.
这些文件是多种语言的本地化版本。
例如,我可能有 3 个同名文件,例如,MyView.strings
但每个文件都位于本地化目录中,例如en.lproj
、it.lproj
或pt-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) )
但是,shell 会根据 的值拆分命令的结果$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
如果您需要能够处理任意文件名,包括带有换行符的文件名,您可以使用mapfile
分隔符并将其设置为 null,还可以使用 (不可移植,但受 GNU 和 BSD 支持find
,因此它应该在您的 mac 上工作)使用空分隔符而不是换行符打印结果-print0
的选项:find
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