我正在尝试学习 bash,并尝试使用 a.sh 中的 bash 脚本列出文件夹中的文件,如下所示:
1: a.sh
2: b.sh
3: c.sh
我查看了 ls 和 find 命令,但它们似乎没有像我想要的那样以数字为前缀。请帮忙!
答案1
有很多方法可以做到这一点。例如,如果您确定文件名不包含换行符,您可以执行以下操作:
$ ls | cat -n
1 a.sh
2 b.sh
3 c.sh
4 d.sh
一种更安全的方法可以处理包含换行符或任何其他奇怪字符的文件名:
$ c=0; for file in *; do ((c++)); printf '%s : %s\n' "$c" "$file"; done
1 : a.sh
2 : b.sh
3 : c.sh
4 : d.sh
要了解为什么后两者更好,请创建一个包含换行符的文件名:
$ touch 'a long file name'
$ touch 'another long filename, this one has'$'\n''a newline character!'
现在,比较两种方法的输出:
$ ls | cat -n
1 a long file name
2 another long filename, this one has
3 a newline character!
4 a.sh
5 b.sh
6 c.sh
7 d.sh
正如您在上面所看到的,解析ls
(这通常是一个坏主意)会导致带有换行符的文件名被视为两个单独的文件。正确的输出是:
$ c=0; for file in *; do ((c++)); printf '%s : %s\n' "$c" "$file"; done
1 : a long file name
2 : another long filename, this one has
a newline character!
3 : a.sh
4 : b.sh
5 : c.sh
6 : d.sh
正如 @Vikyboss 在评论中指出的那样,上面的 shell 解决方案将设置$c
在循环退出后持续存在的变量。为了避免这种情况,您可以unset c
在末尾添加,或使用另一种方法。例如:
$ perl -le 'for(0..$#ARGV){print $_+1 ." : $ARGV[$_]"}' *
1 : a long file name
2 : another long filename, this one has
a newline character!
3 : a.sh
4 : b.sh
5 : c.sh
6 : d.sh
答案2
这行吗?
ls | awk '{print NR": "$0}'
1: andy
2: a.out
3: exclude