使用cut命令将空格用作定界符


328

我想使用空格作为cut命令的定界符。

我可以使用什么语法?


42
不对的,因为切割的man page没有解释这一点,是在一般情况下,不翔实
UncleZeiv

2
同样,在这种情况下,“信息剪切”也无济于事。
cardiff space man

3
@ mklement0(如果我还记得的话),我是在回复一条已删除的评论,该评论认为此问题已在手册页中得到了回答,我认为这是“不正确的”,无论有何充分理由或不-现在,虽然我承认,有可能是这种缺乏信息一个很好的理由,我还是觉得没有共同使用的例子是文档往往是至少刺激性,如果不是完全没用
UncleZeiv

3
@UncleZeiv明白了; 感谢您的澄清;考虑到对此问题的兴趣,可以公平地认为该man页面不够用。让我们来看看:“ -d delim使用delim作为字段分隔符,而不是制表符。” (BSD cut,但GNU版本和POSIX规范几乎相同)。使用外壳来调用cut-典型案例-因此需要你知道如何通常通过一个空间使用参数shell语法,这无疑不是cut男人页的工作。实际示例总是有帮助的,但是,GNU手册页缺少它们。
mklement0

4
尽管选择的答案在技​​术上是正确的,但请考虑选择@ mklement0作为标准答案,以选择最新的更全面的答案,以便将其过滤到顶部。
David LeBauer

Answers:


367
cut -d ' ' -f 2

其中2是所需的以空格分隔的字段的字段号。


2
您能否像在RegEx中那样告诉cut使用任意数量的某个特定字符作为分隔符?例如任意数量的空格,例如\ s +
两栖游戏,2012年

3
@foampile不,我不相信你可以。
乔纳森·哈特利

6
您不能将regexes与一起使用cut,但是可以与之一起cuts尝试“修复”所有cut限制:github.com/arielf/cuts
arielf 2014年

你能得到每三个空间有限的场吗?喜欢cut -d ' ' -f 3,6,9,12,15,18而不必指定每一个数字?
Monocito

169

通常,如果您使用空格作为定界符,则希望将多个空格视为一个,因为您会解析命令输出,以使某些列与空格对齐。(和谷歌搜索导致我在这里)

在这种情况下,单个cut命令是不够的,您需要使用:

tr -s ' ' | cut -d ' ' -f 2

要么

awk '{print $2}'

2
感谢awk示例用法,正是我所需要的。
spazm '16

44

补充现有的,有用的答案;帽子给小费QZ支持鼓励我发布一个单独的答案:

两种不同的机制在这里起作用:

  • (a)cut 本身是否要求传递给-d选项的定界符(在这种情况下为空格)是一个单独的参数,或者是否可以将其直接附加到-d

  • (b)shell在将参数传递给被调用的命令之前通常如何解析参数。

(a)由POSIX公用事业指南(强调我的)引述

如果标准实用程序的摘要显示带有强制性选项参数的选项,则符合标准的应用程序应对该选项及其选项参数使用单独的参数然而,一个符合标准的实现应允许应用程序指定同一参数串的选项,选项参数中间没有字符

换句话说:在这种情况下,因为-d的option-argument是强制性的,所以您可以选择是否将分隔符指定为

  • (s)Ether:一个单独的论点
  • (d)OR:直接附加-d的值。

选择(s)或(d)之后,shell的字符串文字解析-(b)就很重要:

  • 随着办法(S) ,以下所有形式是等价的:

    • -d ' '
    • -d " "
    • -d \<space> # <space> used to represent an actual space for technical reasons
  • 使用方法(d),以下所有形式均等效:

    • -d' '
    • -d" "
    • "-d "
    • '-d '
    • d\<space>

等价由shell的字符串文字处理解释:

上面的cut所有解决方案在看到它们都会得到完全相同的字符串(在每个组中)

  • (s)cut-d视为自己的参数,然后是包含空格字符的单独参数-不带引号或\前缀!

  • (d) cut看到-d 一个空格字符-不带引号或\前缀!-作为相同论点的一部分。

各个组中的形式最终相同的原因是双重的,这取决于外壳如何解析字符串文字

  • Shell允许通过称为quoting的机制按原样指定文字,该机制可以采用几种形式
    • 单引号字符串:里面的内容'...'字面,并形成一个单一的参数
    • 用双引号引起来的字符串:内部的内容"..."也形成单个参数,但可以进行插值(扩展变量引用,例如$var,命令替换($(...)`...`)或算术扩展($(( ... )))。
    • \的-quoting 个别字符:一个\单个字符之前使该字符被解释为一个文字。
  • 引用被补充引用的去除,这意味着一旦壳已解析的命令线,就删除从参数的引用字符(封闭'...'"..."\实例) -从而,该命令被调用不会看到引号字符

36

您还可以说:

cut -d\  -f 2

请注意,反斜杠后面有两个空格。


30
知道“ \”转义下一个字符的人会非常小心地记下下一个字符。像这样使用'\'转义空格字符是一种非常常见的习惯用法。
乔纳森·哈特利

3
@Jonathan Hartley通常大多数代码确实是不可读的:)
Luca Borrione 2012年

1
从linux / unix的角度来看,这\ 是我的第一次尝试,并且有效。我同意与相比' ',它不那么明显,但是我敢肯定,很多人很高兴在这里阅读它,以确保行为安全。为了更好的理解,请参阅下面的@ mklement0评论。
tresf,2015年

@乔纳森·哈特利(JonathanHartley)的更正:“ 知道'\' 的自私者会逃脱下一个字符,并假设其他所有人也知道这一点。” 对于个人项目,这并不适用,但是在团队环境中,这种假设是非常危险的(并且可能代价很高)。
爱德华·尼可迪

1
@EduardNicodei哦,我同意。我们在谈论的是代码的读者(“谁注意到...?”),而不是作者。但是,在某些团队中,也可以假设一定水平的熟练程度。取决于环境。
乔纳森·哈特利

5

刚刚发现您还可以使用"-d "

cut "-d "

测试

$ cat a
hello how are you
I am fine
$ cut "-d " -f2 a
how
am

1
的确-或'-d '
mklement0 2015年

3
需要注意的是cut的角度以下所有的是相同的:"-d "'-d '-d" "-d' ',和-d\<space>:所有形式的直接附加的选项的参数(一个空格)至选项(-d)和结果在确切相同的字符串的时候cut看到它们:单个在外壳程序执行了引号删除
mklement0

1
@ mklement0的答案应该是答案。这是此页面上最全面的内容(即使它是评论)。
tresf,2015年

@QZSupport:非常感谢您的感激和鼓励-它启发了我发表自己的回答以及其他背景信息。
mklement0

1
大声笑令人着迷的发现!
哈里

4

如果数据有多个空格,则用cut很难做到这一点。我发现标准化输入以简化处理很有用。一种技巧是使用sed进行如下标准化。

echo -e "foor\t \t bar" | sed 's:\s\+:\t:g' | cut -f2  #bar

3

scut,类似cut的实用程序(我制作的更智能,但速度较慢),可以将任何perl regex用作中断令牌。默认打破空白,但是您也可以打破多字符正则表达式,替代正则表达式等。

scut -f='6 2 8 7' < input.file  > output.file

因此,以上命令将中断空白列并按此顺序提取(从0开始)cols 6 2 8 7。


0

我有一个包含sed正则表达式和捕获组的答案(我承认有些困惑):

  • \S* - 第一个字
  • \s* -定界符
  • (\S*) -第二个字-已捕获
  • .* -其余部分

作为sed表达式,捕获组需要转义,即\(\)

\1返回的拍摄组的副本,即,在第二个字。

$ echo "alpha beta gamma delta" | sed 's/\S*\s*\(\S*\).*/\1/'
beta

当您查看此答案时,它有些令人困惑,您可能会想到,为什么要打扰?好吧,我希望有人能去“啊哈!” 并将使用此模式通过单个sed表达式解决一些复杂的文本提取问题。

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.