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

我可以使用什么语法呢?


当前回答

补充现有的、有用的答案;向QZ支持者表示敬意,感谢他们鼓励我发表单独的回答:

这里有两种不同的机制:

(a) cut本身是否需要传递给-d选项的分隔符(在本例中为空格)作为一个单独的参数,或者直接将其附加到-d是否可以接受。 (b) shell通常如何在将参数传递给被调用的命令之前解析参数。

(a)引用POSIX公用事业指南来回答(强调我)

如果标准实用程序的SYNOPSIS显示一个带有强制选项参数的选项[…]]符合要求的应用程序应为该选项及其选项参数使用单独的参数。然而,一个符合规范的实现还应该允许应用程序在同一个参数字符串中指定选项和选项参数,而不需要插入字符。

换句话说:在这种情况下,由于-d的选项参数是强制性的,您可以选择是否将分隔符指定为:

(s)任选其一:单独的参数 (d)或:作为直接附加到-d的值。

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

对于不同的方法,以下所有形式都是等效的: -d ' ' -d " " -d \<space> # <space>由于技术原因用于表示实际的空格 对于方法(d),以下所有形式都是等效的: - d ' ' - d”“ “- d” “- d” d \ <空间>

shell的字符串字面值处理解释了等价性:

以上所有解决方案的结果是完全相同的字符串(在每组)的时间cut看到他们:

(s): cut视-d为自己的参数,后面跟着一个单独的参数,该参数包含一个空格字符-不带引号或\前缀! (d): cut看到-d加上一个空格字符-没有引号或\前缀!-作为同一论点的一部分。

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

The shell allows literal to be specified as is through a mechanism called quoting, which can take several forms: single-quoted strings: the contents inside '...' is taken literally and forms a single argument double-quoted strings: the contents inside "..." also forms a single argument, but is subject to interpolation (expands variable references such as $var, command substitutions ($(...) or `...`), or arithmetic expansions ($(( ... ))). \-quoting of individual characters: a \ preceding a single character causes that character to be interpreted as a literal. Quoting is complemented by quote removal, which means that once the shell has parsed a command line, it removes the quote characters from the arguments (enclosing '...' or "..." or \ instances) - thus, the command being invoked never sees the quote characters.

其他回答

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

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

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

你也可以说:

cut -d\  -f 2

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

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

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

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

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

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

Or

awk '{print $2}'

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

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

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

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

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

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