Bash:得到修改的`ls`-like输出(每行多个条目)

时间:2015-03-10 14:31:02

标签: bash multiple-columns ls

如果在命令行中没有其他选项的情况下调用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一样,在修改它们之后(通过例如sedbasename等。 )?

3 个答案:

答案 0 :(得分:5)

(令人惊讶的命名)column命令将执行您想要的操作。

ls | column -c 80

将以80行显示的列显示输出。您可能必须等待输出,因为它必须先确定项目的宽度才能格式化任何内容。

当然,它可以使用任何命令。

您可以使用COLUMNS变量找到您的列(这可能取决于您的shell - 键入set以查看变量列表并找出它),或使用{{1} }命令。

答案 1 :(得分:4)

即使输出远离控制台,

ls -C也会强制多列输出。

答案 2 :(得分:1)

更新免责声明

  • 这个答案对OP不起作用,因为他想首先修改 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
  • 确定终端的最大值。线宽本身 [1]

相比之下,当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中的典型情况)是忽略