我有一个文件夹,里面有几个文件夹。我使用以下命令获取所有文件夹的列表:
ls -1a -d */
它返回如下内容:
folder01/
folder02/
folder03/
...
通常,我会将此脚本的结果存储到文本文件中,然后创建第二个 shell 脚本文件,该文件处理 ls 命令返回的文件夹并将其存储在.sh
文件中以批处理方式运行它们。因此 shell 文件将是这样的:
./process_folder.sh sample/folder01/
./process_folder.sh sample/folder02/
./process_folder.sh sample/folder03/
./process_folder.sh sample/folder04/
正如您所看到的,我运行./process_folder.sh
了 ls 命令的结果,并且还有一个小变化,我sample/
在每个文件夹的名称之前添加了它。
所以问题是我如何使用 shell 中的命令完成所有这些操作?(我记得我可以使用|
或者>
但我记不清细节了)。
答案1
不要以编程方式解析的输出ls
。
的输出ls
是为人类使用而设计的,而不是程序化的。直接解析它可能会以多种方式中断,或多或少有点微妙。举个例子,如果我运行你给出的命令,我会得到不同的输出:
$ mkdir -p newdir/folder0{1,2,3}
$ cd newdir
$ ls -1ad */
folder01//
folder02//
folder03//
$
看到那些双斜线了吗?那是因为我已将其别名ls
为ls --color=auto -F
。
最好使用专门设计用于该工作或至少可以很好地用于该工作的工具。我建议转向find
。
$ mkdir -p newdir/folder0{1,2,3}
$ cd newdir
$ find . -mindepth 1 -maxdepth 1 -type d -printf './process_folder.sh sample/"%P"/\n'
./process_folder.sh sample/"folder03"/
./process_folder.sh sample/"folder01"/
./process_folder.sh sample/"folder02"/
$
-mindepth 1 -maxdepth 1
将搜索限制在给定的起始目录(仅.
在这种情况下)并排除起始目录本身。-type d
将匹配限制在目录中。-printf
是 find 可以采取的操作,它以给定的格式打印有关找到的目录条目的元数据;%P
格式字符串中的 被找到的条目名称减去起始目录所替换。man 1 find
有关更多详细信息,请参阅。
如果您想创建一个稍后运行的脚本,请将输出重定向find
到文件:
$ find . -mindepth 1 -maxdepth 1 -type d -printf './process_folder.sh sample/"%P"/\n' > process_folders.sh
如果您想要一个立即执行命令的单个命令,请将输出通过管道传输find
到 shell 中:
$ find . -mindepth 1 -maxdepth 1 -type d -printf './process_folder.sh sample/"%P"/\n' | bash
这不太可能中断,并且无需花哨地重写命令的输出即可获得所需的结果。照原样,我怀疑唯一可能中断此操作的是目录名称中包含双引号的情况。
答案2
你想要一个循环:
for d in $(ls -1a -d */); do
./process_folder.sh "sample/$d"
done
答案3
您可以尝试以下命令:
find . -type d -mindepth 1 -maxdepth 1 -exec bash -c ' /path/to/process_folder.sh "sample/${0##*/}" ' {} \;
这既找到了有问题的目录,又运行了流程文件夹同时在每个命令上执行:只需一个命令,而不是两个。此外,它不会出现解析问题。