awk '{print $9}'最后 ls -l 列包括文件名中的任何空格

发布于 2024-08-04 18:14:52 字数 205 浏览 2 评论 0原文

如果某些文件中有空格,我如何让 awk 在 ls -l 中输出整个文件名。通常,我可以运行以下命令:

ls -l | awk '{print $9}'

如果文件中有空格,则该命令不起作用。是否也可以以某种方式打印 9 美元、10 美元、11 美元等?

How would I get awk to output the whole file name in ls -l if some of the files have spaces in them. Usually, I can run this command:

ls -l | awk '{print $9}'

That doesn't work if the files have spaces in them. Is it possible to print $9, $10, $11 etc as well somehow?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

缘字诀 2024-08-11 18:14:52

更好的解决方案:首先不要尝试解析 ls 输出。

irc.freenode.org #bash 频道的官方 wiki 解释了为什么这是一个坏主意,以及您可以采取哪些替代方法:http://mywiki.wooledge.org/ParsingLs

使用find,stat 和类似的工具将提供您正在寻找的功能,而不会遇到陷阱(并非所有其中很明显——有些仅在迁移到具有不同 ls 实现的平台时才会发生)。

对于您的具体示例,我猜测您只是试图在当前目录中查找文件(而不是目录);您当前使用 ls -l 的实现存在错误,因为它排除了具有 +t 或 setuid 权限的文件。实现这一点的正确方法如下:

find . -maxdepth 1 -type f -printf '%f\n'

A better solution: Don't attempt to parse ls output in the first place.

The official wiki of the irc.freenode.org #bash channel has an explanation of why this is a Bad Idea, and what alternate approaches you can take instead: http://mywiki.wooledge.org/ParsingLs

Use of find, stat and similar tools will provide the functionality you're looking for without the pitfalls (not all of which are obvious -- some occur only when moving to platforms with different ls implementations).

For your specific example, I'm guessing that you're trying to find only files (and not directories) in your current directory; your current implementation using ls -l is buggy, as it excludes files which have +t or setuid permissions. The Right Way to implement this would be the following:

find . -maxdepth 1 -type f -printf '%f\n'
油饼 2024-08-11 18:14:52

只是为了完成。也可以使用 sed 完成:

# just an exercise in regex matching ...
ls -l | sed -E  -e '1d; s/^([^ ]+ +){8}//' 

Just for completion. It can also be done with sed:

# just an exercise in regex matching ...
ls -l | sed -E  -e '1d; s/^([^ ]+ +){8}//' 
挽清梦 2024-08-11 18:14:52

可能有一种更好的方法,涉及以某种方式组合字段,但是:

$ echo 1 2 3 4 5 6 7 8 9 10 11 12 13 14... | 
  awk '{for (i = 9 ; i <= NF ; i++) printf "%s ", $i}'
9 10 11 12 13 14... 

使用 printf "%s " $i 将打印第 i 个字段,后面有一个空格,而不是换行符。 for 循环只是说从字段 9 到最后一个字段。

There's probably a better approach that involves combining fields somehow, but:

$ echo 1 2 3 4 5 6 7 8 9 10 11 12 13 14... | 
  awk '{for (i = 9 ; i <= NF ; i++) printf "%s ", $i}'
9 10 11 12 13 14... 

Using printf "%s " $i will print the i-th field with a space after it, instead of a newline. The for loop just says to go from field 9 to the last field.

白衬杉格子梦 2024-08-11 18:14:52

如果您仍然坚持使用 ls -l 而不是 find 或其他工具,这是我的解决方案。它并不漂亮且具有破坏性:

  1. 通过 for 循环将 $1 .. $8 设置为 "" 来销毁 $1 .. $8
  2. 这会在 $9 之前留下一堆空格,使用 sub() 命令删除它们
  3. 打印出剩余的内容
ls -l | awk '{for (i = 1; i < 9; i++) $i = ""; sub(/^ */, ""); print}'

If you still insist on the ls -l instead of find or other tools, here is my solution. It is not pretty and destructive:

  1. Destroy $1 .. $8 by setting them to "" via a for loop
  2. That leaves a bunch of spaces preceding $9, remove them using the sub() command
  3. Print out the remaining
ls -l | awk '{for (i = 1; i < 9; i++) $i = ""; sub(/^ */, ""); print}'
自我难过 2024-08-11 18:14:52
ls -l | awk -v x=9 '{print $x}'

我用它来毫无意外地获取目录的文件名。我注意到,如果您不确定文件类型,如果您知道要查看的内容,则 find 解决方案很好而且很花花公子,如果您知道 ls -l 工作得很好,它默认情况下也按字母顺序排序。

ls -l | awk -v x=9 '{print $x}'

I use this for getting filenames of a directory without incident. I noted the find solution which is fine and dandy if you are unsure of the file types, if you know what you are looking at the ls -l works just fine, it also alphabetically orders by default.

呆橘 2024-08-11 18:14:52

一个解决方案是编码&使用 sed 解码单词或字符的空格:

ls -l | sed s/\ /{space}/ | awk '{print $9}' | sed s/{space}/\ /

这将在将行传递给 awk 之前将其替换为 {space} 中的所有空格。该行传递给 awk 后,我们将 {space} 替换回空格。

正如其他人所述,find 是一个更好的解决方案。但如果你确实必须使用awk,你可以尝试这个。

A solution is to encode & decode the space with a word or character by using sed:

ls -l | sed s/\ /{space}/ | awk '{print $9}' | sed s/{space}/\ /

This will replace all spaces in a line with {space} before passing it to awk. After the line has passed to awk, we replace {space} back with space.

find as stated by others is a much better solution. But if you really have to use awk, you can try this.

半城柳色半声笛 2024-08-11 18:14:52
echo 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 | 
  awk 'BEGIN {OFS=ORS=""} ; {for (i=9;i<NF;i++) print $i " "; print $NF "\n"}'
echo 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 | 
  awk 'BEGIN {OFS=ORS=""} ; {for (i=9;i<NF;i++) print $i " "; print $NF "\n"}'
—━☆沉默づ 2024-08-11 18:14:52

如果您对文件名感兴趣,请不要解析 ls -l 输出并使用 ls -1(数字one,而不是小写 >L!)。它只是每行输出一个文件名。

$ touch foo 'bar with spaces' baz
$ ls -1
bar with spaces
baz
foo

If you are interested in filenames, then don’t parse ls -l output and use ls -1 (number one, not lowercase L!). It simply outputs one filename per line.

$ touch foo 'bar with spaces' baz
$ ls -1
bar with spaces
baz
foo
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文