使用空格作为分隔符和剪切命令
我想用空格作为cut
命令的分隔符。
我可以使用什么语法?
cut -d ' ' -f 2
其中2是您想要的空格分隔字段的字段编号。
通常,如果使用空格作为分隔符,则希望将多个空格视为一个空格,因为您parsing的是使用空格alignment某些列的命令的输出。 (和谷歌search引导我在这里)
在这种情况下,单个cut
命令是不够的,你需要使用:
tr -s ' ' | cut -d ' ' -f 2
要么
awk '{print $2}'
你也可以说
cut -d\ -f 2
注意反斜杠后有两个空格。
补充现有的,有帮助的答案; QZ的帽子支持鼓励我发表一个单独的答案:
这里有两个截然不同的机制 :
-
(a)是否需要
cut
自身的分隔符(本例中为空格)传递给-d
选项作为单独的参数,或者是否可以直接将其附加到-d
。 -
(b) shell在将parameter passing给被调用的命令之前通常如何parsing参数。
(a)由POSIX的公用事业指南 (重点是我的)
如果标准实用程序的概要显示带有强制选项参数[…]的选项,则符合的应用程序应该为该选项和其选项参数使用单独的参数 。 但是 ,符合的实现也应允许应用程序在相同的参数string中指定选项和选项参数,而不插入字符 。
换句话说:在这种情况下, 因为-d
的选项参数是必需的 , 所以可以select是否将分隔符指定为 :
- (s)无论如何:一个单独的论点
- (d)OR:作为直接附加到
-d
的值。
一旦你select了(s)或者(d),这就是shell的stringparsing – (b) – 重要的是:
-
有了方法,以下所有forms都是等价的:
-
-d ' '
-
-d " "
-
-d \<space> # <space> used to represent an actual space for technical reasons
-
-
采用方法(d) ,以下所有forms都是等同的:
-
-d' '
-
-d" "
-
"-d "
-
'-d '
-
d\<space>
-
等价性由shell的string处理来解释:
上面的所有解决scheme都会导致完全相同的string (在每个组中)按时间顺序查看它们 :
-
(s) :
cut
把-d
作为自己的参数,后面跟着一个单独的参数,它包含一个空格char – 不带引号或\
prefix !. -
(d) :
cut
看到-d
加空格char – 不带引号或\
前缀! – 作为同一个论点的一部分。
根据shellparsingstring文字的方式 ,各个组中的表单最终是相同的原因是双重的:
- shell允许通过称为引用(quoting)的机制来指定字面值,可以采用多种forms :
- 单引号string:
'...'
的内容是从字面上理解的,并形成一个单一的参数 - 双引号string:
"..."
内的内容也形成一个单一的参数,但可以插值 (展开variables引用,如$var
,命令replace($(...)
或`...`
),或算术扩展($(( ... ))
)。 - 对单个字符的引用:在单个字符之前的一个字符导致该字符被解释为文字。
- 单引号string:
- 引用通过引用移除来补充,这意味着一旦shellparsing了一个命令行,就会从参数 (包括
'...'
或"..."
或\
instances)中删除引号字符 – 因此, 命令调用不会看到引号字符 。
我刚刚发现你也可以用"-d "
:
cut "-d "
testing
$ cat a hello how are you I am fine $ cut "-d " -f2 a how am
scut ,一个类似cut的工具(更聪明,但我做得更慢),可以使用任何perl正则expression式作为破坏标记。 打破空白是默认的,但你也可以打破多字符正则expression式,替代正则expression式等
scut -f='6 2 8 7' < input.file > output.file
所以上面的命令将打破空白的列,并按顺序提取(从0开始)列6 2 8 7。
如果数据具有多个空格,则无法轻松切割。 我发现有时可以使input规范化,以便于处理。 一个诀窍是使用sed进行标准化,如下所示。
echo -e "foor\t \t bar" | sed 's:\s\+:\t:g' | cut -f2 #bar