cut
命令将空格用作定界符。我可以使用什么语法?
#1 楼
cut -d ' ' -f 2
其中2是所需的以空格分隔的字段的字段号。
评论
你能告诉cut像RegEx一样使用任意数量的某个字符作为分隔符吗?例如任意数量的空格,例如\ s +
–两栖动物
2012年11月1日15:42
@foampile不,我不相信你可以。
–乔纳森·哈特利
2012年11月5日,10:51
您不能使用带有cut的正则表达式,但是可以使用试图“修复”所有剪切限制的cuts:github.com/arielf/cuts
–arielf
2014年7月3日4:00
你能得到每三个空间有限的场吗?像cut -d''-f 3,6,9,12,15,18,而不必指定每个数字?
– Monocito
20-4-17 8:00
#2 楼
通常,如果您使用空格作为定界符,则希望将多个空格视为一个,因为您解析了将某些列与空格对齐的命令输出。 (以及Google搜索的内容会引导我到这里)在这种情况下,仅凭一个
cut
命令是不够的,您需要使用:tr -s ' ' | cut -d ' ' -f 2
或
awk '{print }'
评论
感谢您的awk示例用法,正是我所需要的。
– spazm
16年6月15日在6:41
是!这应该是接受的答案,或者至少包含在接受的答案中。我不记得当我不必对空间进行规范化时曾经尝试对空间分隔的数据使用剪切。
–杰里米·布鲁克斯(Jeremy Brooks)
20年7月31日在22:50
#3 楼
补充现有的,有用的答案; QZ支持我们鼓励我发表一个单独的答案的提示:这里有两种不同的机制:
(a)
cut
本身是否要求传递给-d
选项的定界符(在这种情况下为空格)是一个单独的参数,或者是否可以将其直接附加到-d
。(b)在将参数传递给命令之前,shell通常如何解析参数
(a)由POSIX实用程序准则(强调我的)中的引号回答。
如果标准实用程序的摘要显示带有强制性选项参数的选项,符合条件的应用程序应对该选项及其选项参数使用单独的参数。但是,一致的实现还应允许应用程序在同一参数字符串中指定选项和选项参数,而无需插入字符。
换句话说:在这种情况下,因为
-d
是option-argument是强制性的,您可以选择是否将定界符指定为:其他:单独的参数
(d)OR:直接附加值到
-d
。选择(s)或(d)后,壳的字符串文字解析-(b)-很重要:
采用方法时,以下所有形式都是等效的:
-d ' '
-d " "
-d \<space> # <space> used to represent an actual space for technical reasons
采用方法(d),以下所有形式都是等效的:
-d' '
-d" "
"-d "
'-d '
d\<space>
等效性由外壳的字符串文字处理解释:
cut
看到它们时(在每个组中)完全相同的字符串:(s):
cut
将-d
视为自己的参数,然后是一个单独的参数,其中包含空格char-不带引号或\
前缀!。(d):
cut
看到-d
加上一个空格char-不带引号或\
前缀! -作为同一个参数的一部分。基于外壳解析字符串文字的方式,各个组中的形式最终相同的原因是双重的:
shell允许通过称为引号的机制按原样指定文字,该机制可以采用多种形式:
单引号字符串:
'...'
内部的内容按字面意义使用并形成单个参数双引号字符串:
"..."
内的内容也形成单个参数,但可以插值(扩展变量引用,例如$var
,命令替换($(...)
或`...`
),或算术扩展($(( ... ))
)。\
-引用单个字符:单个字符前面的\
导致该字符被解释为文字。引用加上引号删除功能,这意味着一旦外壳程序解析了命令行,它将删除引号字符从参数(包含
'...'
或"..."
或\
实例)中输入s-因此,被调用的命令将永远不会看到引号字符。#4 楼
您也可以说:cut -d\ -f 2
请注意,反斜杠后有两个空格。
评论
知道“ \”转义下一个字符的人会非常小心地记下下一个字符。像这样使用'\'转义空格字符是一种非常常见的习惯用法。
–乔纳森·哈特利
2012年3月21日在9:24
@Jonathan Hartley通常大多数代码确实是不可读的:)
–卢卡·鲍里昂
2012年11月2日13:24
从linux / unix的角度来看,\是我的第一次尝试,并且奏效了。我同意,与“”相比,它不太明显,但我敢肯定,很多人很高兴在这里阅读它,以确保行为安全。为了更好的理解,请参见下面的@ mklement0评论。
– Tresf
2015年5月1日22:14
@乔纳森·哈特利(JonathanHartley)的更正:“知道'\'的自私者会逃脱下一个字符,并假设其他所有人也知道这一点。”对于个人项目,这并不适用,但是在团队环境中,这种假设是非常危险的(并且可能代价很高)。
–爱德华·尼科迪(Eduard Nicodei)
17/09/13在12:14
@EduardNicodei哦,我同意。我们在谈论的是代码的读者(“谁注意到...?”),而不是作者。但是,在某些团队中,也可以假设一定水平的熟练程度。取决于环境。
–乔纳森·哈特利
17/09/13在19:30
#5 楼
我刚刚发现您还可以使用"-d "
:cut "-d "
测试
$ cat a
hello how are you
I am fine
$ cut "-d " -f2 a
how
am
评论
请注意,从cut的角度来看,以下所有内容都是相同的:“ -d”,“ -d,-d”,“ -d”和-d \
–mklement0
2015年4月22日13:28
@ mklement0的答案应该是答案。它是此页面上最全面的(即使它是评论)。
– Tresf
2015年5月1日22:16
@QZSupport:非常感谢您的感激和鼓励-它启发了我发表自己的回答以及其他背景信息。
–mklement0
2015年5月2日,下午3:53
大声笑迷人的发现!
–哈里
18/12/8在9:02
#6 楼
如果数据有多个空格,则用cut很难做到这一点。我发现对输入进行标准化以简化处理很有用。一种技巧是使用sed进行标准化,如下所示。echo -e "foor\t \t bar" | sed 's:\s\+:\t:g' | cut -f2 #bar
#7 楼
scut,类似cut的实用程序(我制作的更智能,但速度较慢),可以将任何perl regex用作中断令牌。默认情况下,打破空白是可以的,但您也可以打破多字符正则表达式,替代正则表达式等。scut -f='6 2 8 7' < input.file > output.file
,因此上述命令将打破空白和按此顺序提取(从0开始)cols 6 2 8 7。
#8 楼
我有一个涉及sed
,正则表达式和捕获组的答案(我承认有些困惑):\S*
-第一个单词\s*
-定界符(\S*)
-第二个单词-已捕获.*
-该行的其余部分作为
sed
表达式,需要对捕获组进行转义,即\(
和\)
。
返回捕获的组的副本,即第二个单词。 $ echo "alpha beta gamma delta" | sed 's/\S*\s*\(\S*\).*//'
beta
当您看到这个答案时,它有些令人困惑,您可能会想到,为什么要打扰?好吧,我希望有人能去“啊哈!”并将使用此模式通过单个
sed
表达式解决一些复杂的文本提取问题。
评论
不正确,cut的手册页无法解释这一点,并且通常情况下信息不足同样,“信息剪切”在这种情况下也没有改善。
@ mklement0(如果我还记得的话),我是在回复一条已删除的评论,该评论认为此问题已在手册页中得到了回答,我认为这是“不正确的”,无论有何充分理由还是不-现在,尽管我承认可能缺乏信息是有充分理由的,但我仍然认为没有通用用法示例的文档通常至少令人恼火,即使不是完全没用的
@UncleZeiv明白了;感谢您的澄清;考虑到对此问题的兴趣,可以公平地假设手册页不够用。让我们看一下:“ -d delim使用delim作为字段定界符而不是制表符。” (削减了BSD,但GNU版本和POSIX规范几乎相同)。因此,使用shell调用cut是一种典型的情况,因此需要您知道如何使用shell语法将空格作为参数传递,这可以说不是cut手册页的工作。实际示例总是有帮助的,但是,GNU手册页缺少它们。
尽管所选的答案在技术上是正确的,但请考虑选择@ mklement0作为标准答案,以使其更靠前。