在当前目录运行命令ls
并获取输出:
$ ls
Applications Documents Library Music Public
Desktop Downloads Movies Pictures
我想列举一下:
1. Applications
2. Desktop
3. Documents
4. Downloads
5. Library
6. Movies
7. Music
8. Pictures
9. Public
less
这可以通过中间方式实现
ls | less -N
如何直接明了地列举它们?
答案1
或者简单地这样做:
ls -b |nl -s '. ' -w 1
1. a\ file\ with\ nonewline
2. a\ file\ with\nnewline
3. a\ file\ with\ space
4. afile
从man nl
:
-s, --number-separator=STRING
add STRING after (possible) line number
-w, --number-width=NUMBER
use NUMBER columns for line numbers
答案2
您应该将 的输出通过管道传输ls
到另一个命令。我的建议是awk
使用这边走:
$ ls -b --group-directories-first | awk '{print NR ". " $0}'
1. dir1
2. dir2
3. dir3
4. z-dir1
5. z-dir2
6. z-dir3
7. file1
8. file2
9. file3
10. file4
11. file5
12. file6
13. file7
14. file\nnewline
请注意,该文件的名称中
file\nnewline
包含换行符\n
,可通过选项进行转义-b
。该选项
--group-directories-first
将在文件之前输出目录。
另一种可能的方法是使用 for 循环(但在这种情况下将目录放在列表的开头会变得更加困难):
n=1; for i in *; do echo $((n++)). $i; done
答案3
如果只是显示一个数字,那么您可以选择以下几种方式less -N
:
$ ls |cat -n
$ ls |nl
如果您想要自定义输出编号,那么我建议您使用find
并执行您想要打印的任何操作:
find . -exec bash -c 'for fnd; do printf "%d. %s\n" "$((++i))" "$fnd"; done ' _ {} +
POSIXly,你可以这样做:
find . -exec sh -c 'for fnd; do i=$((i+1)); printf "%d.\t%s\n" "$i" "$fnd"; done ' _ {} +
答案4
您也可以使用一个简短的 Bash 脚本完全完成此操作:
#!/bin/bash
set -eu
shopt -s nullglob
[ "$#" -eq 0 ] || cd -- "$1"
i=0
for f in *; do
printf '%d. %s\n' "$((++i))" "${f//$'\n'/^N}"
done |
cat -vt
您甚至可以更进一步,为超过 9 个结果填充行号:
#!/bin/bash
set -eu
shopt -s nullglob
[ "$#" -eq 0 ] || cd -- "$1"
ls=(*)
pad=${#ls[@]}
pad=${#pad}
i=0
for f in *; do
printf '%*d. %s\n' "$pad" "$((++i))" "${f//$'\n'/^N}"
done |
cat -vt
用法
假设您将脚本保存为numbered-ls.sh
当前工作目录中的可执行文件:
./numbered-ls.sh [DIRECTORY]
该参数DIRECTORY
是可选的,默认为当前工作目录。
解释
如果使用参数调用脚本,则将工作目录更改为第一个参数中的路径。
匹配当前工作目录的所有条目并查看它们。对于每个条目,增加一个计数器并将其值与条目名称一起打印。条目名称中的换行符将替换为
^N
。通过管道传输输出,
cat -vt
以便妥善处理包含终端可能解释为控制字符的不可打印字符的文件名。