使用cut命令使用空格作为分隔符

我想用cut命令使用空格作为分隔符。

我可以使用什么语法呢?

402383 次浏览
cut -d ' ' -f 2

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

你也可以说:

cut -d\  -f 2

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

可鄙的人,一个类似cut的实用程序(我做的更聪明但更慢),可以使用任何perl regex作为中断令牌。在空格上中断是默认的,但您也可以在多字符正则表达式、替代正则表达式等上中断。

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

因此,上面的命令将在空格上打断列,并按此顺序提取(以0为基数)cols 6 2 8 7。

通常,如果使用空格作为分隔符,则希望将多个空格视为一个空格,因为要用空格对齐一些列来解析命令的输出。(谷歌搜索把我带到了这里)

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

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

awk '{print $2}'

刚刚发现,你也可以使用"-d ":

cut "-d "

测试

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

补充现有的、有用的答案;向QZ支持鼓励我发布一个单独的答案:

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

  • (a) cut 本身是否需要传递给-d选项的分隔符(在本例中为空格)为单独参数,或者将直接附加到-d是否可以接受。

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

(a)通过引用实用程序的POSIX指南来回答(强调我的)

如果一个标准实用程序的概要显示一个带有强制性的选项参数的选项[…]符合要求的应用程序。然而,符合规范的实现应该also允许应用程序在同一个参数字符串中指定选项和选项参数,而不需要中间的字符

换句话说:在本例中,因为-d的选项参数是mandatory您可以choose是否指定分隔符为:

  • (s) EITHER: a < em > < / em >参数分开
  • (d) OR:作为值直接连接-d

一旦你选择了(s)或(d),它是壳牌的字符串文本解析- (b) -重要的:

  • 对于(年代)方法,以下所有形式都是等效的:

    • -d ' '
    • -d " "
    • -d \<space> # <space> used to represent an actual space for technical reasons
    • 李< / ul > < / >
    • 对于(d)方法,以下所有形式都是等效的:

      • -d' '
      • -d" "
      • "-d "
      • '-d '
      • d\<space>
      • 李< / ul > < / >

      等价性由壳牌的字符串字面值处理解释:

      所有cut看到它们时,上述解决方案会导致完全相同的字符串(在每组中):

      • (s): cut看到-d,作为它的自己的参数,后面跟着一个单独的参数,其中包含一个空格字符-不带引号或\前缀!

      • (d): cut看到-d + 是一个空格字符-没有引号或\前缀!-作为same参数的一部分。

      基于如何shell解析字符串字面量,各自组中的形式最终相同的原因有两个:

        shell允许从就像一种机制叫做引用指定字面量,可以取多种形式:
        • 使用单引号字符串:'...'内的内容取字面上的并形成参数
        • 双引号字符串:"..."内的内容也形成了参数,但受制于插值(展开变量引用,如$var,命令替换($(...)`...`),或算术展开($(( ... )))。
        • __abc0 - quote 个人字符:单个字符前面的\导致该字符被解释为字面量。
        • 李< / ul > < / >
        • 引用由引用删除补充,这意味着一旦shell解析了一个命令行,它就从参数中删除引号字符(包含'...'"..."\实例)——因此,被调用的命令永远不会看到引号字符

如果数据有多个空格,你就不能简单地用cut来做。我发现规范化输入有助于简化处理。一个技巧是使用sed进行规范化,如下所示。

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

我有一个答案(我承认有些令人困惑的答案),涉及__abc0,正则表达式和捕获组:

  • \S* -第一个词
  • \s* -分隔符
  • (\S*) -第二个单词-捕获
  • .* -行其余部分

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

\1返回捕获组的副本,即第二个单词。

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

当你看到这个答案时,你可能会觉得有些困惑,你可能会想,为什么要麻烦呢?好吧,我希望有些人,可能会“啊哈!”,并将使用此模式解决一些复杂的文本提取问题与一个sed表达式。