如何仅在ls -Al中输出文件名(带空格)?


78

我应该只用这种结构回显文件或目录的名称:

ls -Al | while read string
do
...
done

ls -Al 输出:

drwxr-xr-x  12 s162103  studs         12 march 28 12:49 personal domain
drwxr-xr-x   2 s162103  studs          3 march 28 22:32 public_html
drwxr-xr-x   7 s162103  studs          8 march 28 13:59 WebApplication1

例如,如果我尝试:

ls -Al | while read string
do
echo "$string" | awk '{print $9}
done

然后仅输出没有空格的文件和目录。如果文件或目录具有“个人域”之类的空格,则只能是“个人”一词。

我需要一个非常简单的解决方案。也许有比awk更好的解决方案。


2
为什么不只是ls -Al *' '*呢?解析ls输出永远不会带来任何好处。
manatwork 2013年

1
如果您需要可以在任何* nix中使用的功能,请尝试避免使用ls -Al | while。一种简单而可靠的方法是for string in *; do echo "$string"; done
forcefsck 2013年

只需要这种结构..好吧,不是简单的任何解决方案!
Alex Zern 2013年

1
为什么需要 ls?解析ls和“在所有* nix中工作,并且如果发生什么事情都不会中断”的效果不佳。
terdon

Answers:


97

确实不应该解析的输出ls。如果这是家庭作业,您必须这样做,那么您的教授不知道他们在说什么。你为什么不做这样的事情:

很好...

find ./  -printf "%f\n"

要么

for n in *; do printf '%s\n' "$n"; done

不好

如果您真的想使用ls,可以通过执行以下操作使其更加健壮:

ls -lA | awk -F':[0-9]* ' '/:/{print $2}'

...和丑陋的

如果您坚持以错误,危险的方式执行操作,而只需要使用while循环,请执行以下操作:

ls -Al | while IFS= read -r string; do echo "$string" | 
    awk -F':[0-9]* ' '/:/{print $2}'; done

严重的是,只是不要。


drwx------ 2 s162103 studs 3 oct. 9 2012 .ssh drwxr-xr-x 3 s162103 studs 6 oct. 25 09:02 .subversion drwxrwxrwt 3 s162103 studs 3 nov. 15 2012 .TempoItems有时我没有时间约会,只有年份和
呆滞

1
@AlexZern好吧,这就是您不解析输出的原因之一ls
terdon

2
@AlexZern为什么-l仍然需要开关?如果只需要文件名,请运行ls -A。使用-ljust会使您的生活更加困难,因为现在您必须解析输出。
terdon

因为我需要其他信息,例如访问权限,日期,所有者等。而且我写了一个巨大的脚本,除了打印文件和带空格的目录名之外,它都很好用。
Alex Zern 2013年

3
好吧。我们这里有一个XY问题ls并不是获得所需东西的最佳方法。您为什么不发布一个新问题来解释您想要收集的信息,我们可以建议您这样做的方法。另外,您可以按原样使用脚本,并使用上面的建议之一仅打印名称。但是认真的是,不要解析ls,只是告诉我们您在一个新问题中想要做什么。
terdon

74

ls -A1* 是否有某些原因不起作用?

例如:

$ touch file1 file2 file\ with\ spaces
$ ls -Al
total 0
-rw-r--r-- 1 bahamat bahamat 0 Mar 30 22:31 file1
-rw-r--r-- 1 bahamat bahamat 0 Mar 30 22:31 file2
-rw-r--r-- 1 bahamat bahamat 0 Mar 30 22:31 file with spaces
$ ls -A1
file1
file2
file with spaces
$

*注意:这是一个大写字母A和一个数字。


4
-1是天才。我不知道那是可用的。(我知道我知道。RTFM)
The Lazy Coder 2015年

如果您想列出其他目录中的文件名(例如〜/ projects),则仅适用于当前目录,那么您将获得完整路径而不是文件名
thecotne 2015年

在Mac 10.9.5上,@ thecotne仅列出文件名。您正在使用什么操作系统?
AJP

我正在运行
ls〜

3
@TheLazyCoder不应阅读该手册。
c24w

41

我不知道为什么没有人提到这个简单的命令:

ls -a | sort

2
辉煌!知道如何通过管道将sort多列块取消旋转为单列吗?
msciwoj

@msciwoj它只是需要用空格分隔的任何字符串,并将它们打印排序方式endlines分离

完善!为什么这不是真正的答案!?
夏期剧场

3
之所以在这里工作是因为当它的输出没有到达终端时ls会还原为ls -1(单列输出)(并禁用不可打印的字符引用/替换; @Kusalananda,ls如果您仍然不兼容POSIX)。ls输出已经排序。因此,sort将其管道传输至最佳状态将无济于事,更糟糕的是,会破坏输出(如果文件名包含换行符),或者输出非文本文件名失败。ls -a | cat会更好。甚至更好ls -A1如前所述(因为你通常希望替换/终端上显示时引用)
斯特凡Chazelas

1
@StéphaneChazelas注意。ls当输出不是终端时,行为会有所不同。
库沙兰丹

3

您无法解析的输出ls,更不用说解析了,ls -l因为换行符就像空格与文件名中的任何字符一样有效。另外,您需要考虑符号链接的输出,例如... foo -> bar

-l如果只想要文件名,为什么仍要使用?

做就是了:

for file in *; do
  ...
done

如果要包括点文件(.和除外..),具体取决于外壳:

zsh

for file in *(ND); do
  ...
done

bash

shopt -s nullglob dotglob
for file in *; do
  ...
done

ksh93

FIGNORE='@(.|..)'
for file in ~(N)*; do
  ...
done

POSIXly:

for file in .[!.]* ..?* *; do
  [ -e "$file" ] || [ -L "$file" ] || continue
  ...
done

1

怎么样:

for file in * .[!.]*
do
  printf "%s\n" "$file"
done

1
ls -Al | tr -s ' ' | cut -f9- -d' '

用tr将多个空格压缩为单个空格,然后可以使用cut拆分字段




By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.