如何仅使用 Bash 数组反向打印目录的内容?
How can I print the contents of a directory in reverse just using Bash arrays?
目前,我正在做这个家庭作业:
Write a Bash script, reverse.sh
, which reverses the contents of a directory passed as a parameter. Assuming /my/dir
contains cache cron games lib log run tmp
, your program reverse.sh /my/dir
will return tmp run log lib games cron cache
. Use an array and two functions: main()
and reverse()
. You will manually manipulate the list as we did today. DO NOT use the built-in command sort -r
.
现在,我决定先使用一个函数来获得正确的输出,这不是我的问题。到目前为止,这是我的脚本:
function main(){
p=
cd $p
reverse $p
}
function reverse(){
local p2=
local ARRAY=()
local count=0
for entry in $p2*
do
((count++))
ARRAY+=($entry)
done
while [ $count -gt -1 ]; do
echo ${ARRAY[$count]}
((count--))
done
}
main
但是,无论我在 运行 脚本时添加什么目录作为参数,我每次都得到相同的输出。
如果您的脚本要将 /my/dir 作为参数,您需要
for entry in $p2/*
原样,它适用于 main /my/dir/
。除了目录名称包含在每个数组元素中之外。您可以使用 basename 或 cd 修复它。
但是如果您在脚本中对 main 的调用应该传递命令行参数,则您需要结束脚本
main ""
p=
将不起作用,因为未使用任何参数调用 main
(参数不会自动从命令行传递给函数)。修复是将所有命令行参数传递给函数:
main $@
在 Bash
中取消偏移位置参数
我确定您的家庭作业正在尝试教给您一些特别的东西,但即使您应该用 Bash 数组模拟堆栈,这也需要很长的路要走。在 Bash 中,您可以通过利用位置参数和 shift
内置函数来使用单个局部变量来完成此操作。例如:
# Function to sort names by emulating unshifting onto a stack.
reverse () {
local -a result
for dir in "$@"; do
result=("" "${result[@]}") # unshift onto stack
shift # remove from positional params
done
echo "${result[@]}"
}
reverse cache cron games lib log run tmp
tmp run log lib games cron cache
出于演示的目的,此函数假设正在向其传递要排序的姓名列表;它不假设您如何收集这些名称,因为 bike-shedding. However, on systems with GNU ls, you might consider reverse $(ls -Q /path/to/dir)
(do not quote the command substitution) 作为一个实用的解决方案,可以处理最常见的用例。
自行车脱落
专业质量的脚本需要比合理大小的示例中提供的更多的防弹功能。注意事项包括:
- 处理文件名中的空格、换行符和其他合法(但不常见)字符。
- 处理 nullglob 扩展。
- 正在测试 glob 和参数的目录属性。
- 处理符号链接、absolute/relative 路径和各种扩展验证。
- 处理超过
getconf ARG_MAX
或 MAX_ARG_STRLEN. 的硬编码值的 glob
- 等等,令人作呕。
我的建议是为您已知的数据集编写 "good enough" 的代码,而不是试图应对所有可能的边缘情况。了解您的数据和环境始终很重要,这样您就不会过度设计问题。
目前,我正在做这个家庭作业:
Write a Bash script,
reverse.sh
, which reverses the contents of a directory passed as a parameter. Assuming/my/dir
containscache cron games lib log run tmp
, your programreverse.sh /my/dir
will returntmp run log lib games cron cache
. Use an array and two functions:main()
andreverse()
. You will manually manipulate the list as we did today. DO NOT use the built-in commandsort -r
.
现在,我决定先使用一个函数来获得正确的输出,这不是我的问题。到目前为止,这是我的脚本:
function main(){
p=
cd $p
reverse $p
}
function reverse(){
local p2=
local ARRAY=()
local count=0
for entry in $p2*
do
((count++))
ARRAY+=($entry)
done
while [ $count -gt -1 ]; do
echo ${ARRAY[$count]}
((count--))
done
}
main
但是,无论我在 运行 脚本时添加什么目录作为参数,我每次都得到相同的输出。
如果您的脚本要将 /my/dir 作为参数,您需要
for entry in $p2/*
原样,它适用于 main /my/dir/
。除了目录名称包含在每个数组元素中之外。您可以使用 basename 或 cd 修复它。
但是如果您在脚本中对 main 的调用应该传递命令行参数,则您需要结束脚本
main ""
p=
将不起作用,因为未使用任何参数调用 main
(参数不会自动从命令行传递给函数)。修复是将所有命令行参数传递给函数:
main $@
在 Bash
中取消偏移位置参数我确定您的家庭作业正在尝试教给您一些特别的东西,但即使您应该用 Bash 数组模拟堆栈,这也需要很长的路要走。在 Bash 中,您可以通过利用位置参数和 shift
内置函数来使用单个局部变量来完成此操作。例如:
# Function to sort names by emulating unshifting onto a stack.
reverse () {
local -a result
for dir in "$@"; do
result=("" "${result[@]}") # unshift onto stack
shift # remove from positional params
done
echo "${result[@]}"
}
reverse cache cron games lib log run tmp
tmp run log lib games cron cache
出于演示的目的,此函数假设正在向其传递要排序的姓名列表;它不假设您如何收集这些名称,因为 bike-shedding. However, on systems with GNU ls, you might consider reverse $(ls -Q /path/to/dir)
(do not quote the command substitution) 作为一个实用的解决方案,可以处理最常见的用例。
自行车脱落
专业质量的脚本需要比合理大小的示例中提供的更多的防弹功能。注意事项包括:
- 处理文件名中的空格、换行符和其他合法(但不常见)字符。
- 处理 nullglob 扩展。
- 正在测试 glob 和参数的目录属性。
- 处理符号链接、absolute/relative 路径和各种扩展验证。
- 处理超过
getconf ARG_MAX
或 MAX_ARG_STRLEN. 的硬编码值的 glob
- 等等,令人作呕。
我的建议是为您已知的数据集编写 "good enough" 的代码,而不是试图应对所有可能的边缘情况。了解您的数据和环境始终很重要,这样您就不会过度设计问题。