如果在命令行中没有其他选项的情况下调用ls
,则每行会有多个条目。
受挫的例子:
$ ls mydir/*.tar.gz
mydir/foo.tar.gz mydir/bar.tar.gz mydir/baz.tar.gz
但是如果你想以某种方式修改输出,你每行会得到一个条目:
$ ls mydir/*.tar.gz | sed "s/\.tar\.gz//g"
mydir/foo
mydir/bar
mydir/baz
有很多条目,这会变得很麻烦 - 我希望多个对齐的列回来。
我试图提出find mydir -name "*.tar.gz" -printf ...
或... -exec ...
,甚至(yuk!)for file in $(find ...)
的内容,但是任何我能想到的东西都是非常不优雅(想想计数器变量,模数和猜测终端宽度......)。
是否有一些优雅的方法可以在多列输出中获取几个文件名,就像使用vanilla ls
一样,在修改它们之后(通过例如sed
,basename
等。 )?
答案 0 :(得分:5)
(令人惊讶的命名)column
命令将执行您想要的操作。
ls | column -c 80
将以80行显示的列显示输出。您可能必须等待输出,因为它必须先确定项目的宽度才能格式化任何内容。
当然,它可以使用任何命令。
您可以使用COLUMNS
变量找到您的列(这可能取决于您的shell - 键入set
以查看变量列表并找出它),或使用{{1} }命令。
答案 1 :(得分:4)
ls -C
也会强制多列输出。
答案 2 :(得分:1)
更新和免责声明:
ls
输出,然后然后将其列出来;因此,必须在单独的传递中应用列,以后,这是accepted answer通过column -c <n>
提供的。ls
输出时有效。
ls
如何决定如何格式化其输出以及最大值的可能有趣的背景信息。它假设的线宽。构建于rojomoke's promising answer,指出-C
明确请求ls
的多列输出:
<强> TL;博士强>
模拟ls
的多列终端输出 使用当前文件或通过管道发送内容时终端的最大值行宽 (单字符显示列数),使用 COLUMNS=$(tput cols) ls -C
; e.g:
COLUMNS=$(tput cols) ls -C | cat # `| cat` is an example command to show pipe behavior
显然,你也可以选择一个独立于当前终端的固定号码;例如,COLUMNS=120 ls -C ...
如果没有COLUMNS=...
前缀,则会根据最大值进行分段。线宽80
,与终端窗口的实际宽度无关。
注意:以下内容部分是推测性的。如果我错了,请告诉我。
ls
,当输出到终端 时:
-C
)相比之下,当ls
的标准输出连接到管道或输出文件 时,它
-1
)-C
时,它取自COLUMNS
环境变量的行宽(不是 shell 变量);如果没有这样的变量,则默认为80
。在bash
个shell中,$COLUMNS
通常是仅在交互式shell 中设置的 shell 变量,而不是环境变量 - 换句话说:$COLUMNS
已定义,但未导出。
要让ls
尊重$COLUMNS
变量,您必须将其定义为 environment 变量。
最干净的方法是在ls
的调用(一般模式为:<envVar>=<value> <commmand> ...
)之前添加 ad-hoc,命令本地环境变量定义:
由于tput cols
返回当前终端的线宽,我们得到:
COLUMNS=$(tput cols) ls -C ...
tput cols
也适用于脚本,因此它是强大的方法;交互式地,看似毫无意义的命令COLUMNS=$COLUMNS ls -C
也会起作用。
请注意,ls
在输出到终端时甚至会尊重COLUMNS
环境变量。
[1]也就是说,它不是需要环境变量COLUMNS
,但如果已定义则尊重它。请注意,名为COLUMNS
的(未导出的) shell 变量(在交互式shell中的典型情况)是忽略。