How would I get awk to output $9 $10 $11 etc as some of my files have spaces in them.
我如何得到awk输出$9 $10 $11等等,因为我的一些文件中有空格。
ls -l | grep ^- | awk '{print $9}'
7 个解决方案
#1
30
A better solution: Don't attempt to parse ls output in the first place.
一个更好的解决方案:首先不要尝试解析ls输出。
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
irc.freenode.org #bash频道的官方wiki解释了为什么这是一个坏主意,以及可以采用什么替代方法: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).
使用find、stat和类似工具将提供您正在寻找的功能,而不存在缺陷(并非所有缺陷都很明显——有些缺陷只在迁移到具有不同ls实现的平台时出现)。
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:
对于您的特定示例,我猜测您试图在当前目录中只查找文件(而不是目录);使用ls -l的当前实现存在bug,因为它排除了具有+t或setuid权限的文件。实现这一目标的正确方法如下:
find . -maxdepth 1 -type f -printf '%f\n'
#2
2
Just for completion. It can also be done with sed:
只是为了完成。还可以用sed完成:
# just an exercise in regex matching ...
ls -l | sed -E -e 1d -e /^[^-]/d -e 's/^([^ ]+ +){8}//'
#3
1
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.
使用printf“%s”$,我将在第i个字段后面加上空格,而不是换行。for循环说从第9场到最后一个场。
#4
1
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"}'
#5
1
If you still insist on the ls -l instead of find or other tools, here is my solution. It is not pretty and destructive:
如果您仍然坚持使用ls -l而不是find或其他工具,这是我的解决方案。它并不美丽和具有破坏性:
- Destroy $1 .. $8 by setting them to "" via a for loop
- 摧毁美元1 . .$8,通过for循环将它们设置为“”
- That leaves a bunch of spaces preceding $9, remove them using the sub() command
- 这就在$9之前留下了一串空格,使用sub()命令删除它们
-
Print out the remaining
打印出剩下的
ls -l | awk '{for (i = 1; i < 9; i++) $i = ""; sub(/^ */, ""); print}'
l | awk '{for (i = 1;我< 9;我+ +)$ = " ";子(/ ^ * / " ");打印}’
#6
1
A solution is to encode & decode the space with a word or character by using sed:
一种解决方案是使用sed对空格进行编码和解码:
ls -l | grep ^- | 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.
这将用{space}替换行中的所有空格,然后将其传递给awk。行传递给awk后,我们用空格替换{space}返回。
find
as stated by others is a much better solution. But if you really have to use awk, you can try this.
发现别人所说的是一个更好的解决方案。但是如果你真的需要awk,你可以试试这个。
#7
1
ls -l | grep ^- | 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.
我用它来获取目录的文件名,而不会发生意外。我提到了find解决方案,如果你不确定文件类型,如果你知道你在看什么ls -l很好,它也是默认的字母顺序。
#1
30
A better solution: Don't attempt to parse ls output in the first place.
一个更好的解决方案:首先不要尝试解析ls输出。
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
irc.freenode.org #bash频道的官方wiki解释了为什么这是一个坏主意,以及可以采用什么替代方法: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).
使用find、stat和类似工具将提供您正在寻找的功能,而不存在缺陷(并非所有缺陷都很明显——有些缺陷只在迁移到具有不同ls实现的平台时出现)。
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:
对于您的特定示例,我猜测您试图在当前目录中只查找文件(而不是目录);使用ls -l的当前实现存在bug,因为它排除了具有+t或setuid权限的文件。实现这一目标的正确方法如下:
find . -maxdepth 1 -type f -printf '%f\n'
#2
2
Just for completion. It can also be done with sed:
只是为了完成。还可以用sed完成:
# just an exercise in regex matching ...
ls -l | sed -E -e 1d -e /^[^-]/d -e 's/^([^ ]+ +){8}//'
#3
1
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.
使用printf“%s”$,我将在第i个字段后面加上空格,而不是换行。for循环说从第9场到最后一个场。
#4
1
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"}'
#5
1
If you still insist on the ls -l instead of find or other tools, here is my solution. It is not pretty and destructive:
如果您仍然坚持使用ls -l而不是find或其他工具,这是我的解决方案。它并不美丽和具有破坏性:
- Destroy $1 .. $8 by setting them to "" via a for loop
- 摧毁美元1 . .$8,通过for循环将它们设置为“”
- That leaves a bunch of spaces preceding $9, remove them using the sub() command
- 这就在$9之前留下了一串空格,使用sub()命令删除它们
-
Print out the remaining
打印出剩下的
ls -l | awk '{for (i = 1; i < 9; i++) $i = ""; sub(/^ */, ""); print}'
l | awk '{for (i = 1;我< 9;我+ +)$ = " ";子(/ ^ * / " ");打印}’
#6
1
A solution is to encode & decode the space with a word or character by using sed:
一种解决方案是使用sed对空格进行编码和解码:
ls -l | grep ^- | 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.
这将用{space}替换行中的所有空格,然后将其传递给awk。行传递给awk后,我们用空格替换{space}返回。
find
as stated by others is a much better solution. But if you really have to use awk, you can try this.
发现别人所说的是一个更好的解决方案。但是如果你真的需要awk,你可以试试这个。
#7
1
ls -l | grep ^- | 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.
我用它来获取目录的文件名,而不会发生意外。我提到了find解决方案,如果你不确定文件类型,如果你知道你在看什么ls -l很好,它也是默认的字母顺序。