我想使用空间作为cut命令的扩展。我可以使用什么语法来实现这一点?
cut
cwtwac6a1#
cut -d ' ' -f 2
其中2是所需的空格分隔字段的字段编号。
kyks70gy2#
通常,如果使用空格作为空格,则需要将多个空格视为一个空格,因为您要分析命令的输出,将某些列与空格对齐。(Google搜索将我带到这里)在这种情况下,单个cut命令是不够的,您需要使用用途:
tr -s ' ' | cut -d ' ' -f 2
或
awk '{print $2}'
这是因为AWK的默认输入字段分隔符是一个或多个空白字符;在正则表达式中,它类似于[ \t]+。AWK解决方案具有透明地处理数据行上的前导/尾随空格的额外好处,而tr + cut解决方案则没有。
[ \t]+
tr
0lvr5msh3#
补充现有的有用答案;向QZ Support致敬,鼓励我发布一个单独的答案:
两种不同的机制在这里发挥作用:
-d
(a)是回答了一个报价从POSIX guidelines for utilities(强调地雷)如果一个标准实用程序的概要显示了一个带有 mandatory option-argument [.]的选项,那么符合要求的应用程序应该为该选项及其option-argument使用 separate arguments。然而,一个一致的实现应该 * 也 * 允许应用程序在同一个参数串中指定选项和选项参数,而不需要插入字符**。换句话说:在这种情况下,**因为-d的option-argument是 mandatory,你可以 * 选择 * 是否指定参数:
注意:cut的 GNU 实现,默认情况下可以在许多Linux发行版上找到,支持--delimiter作为-d的更具描述性的别名。与-d相同的注意事项,除了直接附加option-argument需要使用=作为分隔符,而 no 分隔符与-d一起使用;例如,在一个实施例中,echo 'one two' | cut --delimiter=' ' -f 1与echo 'one two' | cut -d' ' -f 1一旦你选择了(s)或(d),那么 shell 的字符串字面量解析-(B)-就很重要了:
--delimiter
=
echo 'one two' | cut --delimiter=' ' -f 1
echo 'one two' | cut -d' ' -f 1
-d ' '
-d " "
-d \
\<space>
-d' '
-d" "
"-d "
'-d '
d\
等价性可以通过 shell 的字符串处理来解释:以上所有解决方案在cut看到它们的时候会产生 * 完全相同的字符串 *(在每组中):
*(s):cut将-d视为其 * 自己的 * 参数,后跟一个包含空格字符的 separate 参数-然后不带引号或\前缀!.*(d):cut看到-d * 加上 * 一个空格字符-然后没有引号或\前缀!作为“相同”的一部分。
\
各个组中的形式最终相同的原因是双重的,基于**shell* 如何解析 * 字符串字面量 *:
'...'
"..."
$var
$(...)
...
$(( ... ))
6g8kf2rb4#
你也可以说:
cut -d\ -f 2
注意反斜杠后面有两个空格。
soat7uwm5#
我刚刚发现你也可以使用"-d ":
cut "-d "
$ cat a hello how are you I am fine $ cut "-d " -f2 a how am
368yc8dk6#
例如,如果数据有多个空格,你就不能很容易地用cut来完成。我发现规范化输入以便于处理是很有用的。一个技巧是使用sed进行规范化,如下所示。
echo -e "foor\t \t bar" | sed 's:\s\+:\t:g' | cut -f2 #bar
lmvvr0a87#
scut,一个类似cut的实用程序(我做的更聪明但更慢),可以使用任何perl正则表达式作为中断标记。在空白处中断是默认的,但是你也可以在多字符正则表达式、替代正则表达式等处中断。
scut -f='6 2 8 7' < input.file > output.file
所以上面的命令会在空白处断开列,并按此顺序提取(从0开始的)字符串6 2 8 7。
xzabzqsa8#
我有一个答案(我承认有点混乱的答案),涉及sed,正则表达式和捕获组:
sed
\S*
\s*
(\S*)
.*
作为sed表达式,捕获组需要转义,即\(和\)。\1返回捕获的组的副本,即第二个词。
\(
\)
\1
$ echo "alpha beta gamma delta" | sed 's/\S*\s*\(\S*\).*/\1/' beta
当你看到这个答案时,你可能会想,为什么要这么麻烦呢?好吧,我希望有些人,可能会说“啊哈!“,并将使用此模式来解决一些使用单个sed表达式的复杂文本提取问题。
8条答案
按热度按时间cwtwac6a1#
其中2是所需的空格分隔字段的字段编号。
kyks70gy2#
通常,如果使用空格作为空格,则需要将多个空格视为一个空格,因为您要分析命令的输出,将某些列与空格对齐。(Google搜索将我带到这里)
在这种情况下,单个
cut
命令是不够的,您需要使用用途:或
这是因为AWK的默认输入字段分隔符是一个或多个空白字符;在正则表达式中,它类似于
[ \t]+
。AWK解决方案具有透明地处理数据行上的前导/尾随空格的额外好处,而tr
+cut
解决方案则没有。0lvr5msh3#
补充现有的有用答案;向QZ Support致敬,鼓励我发布一个单独的答案:
两种不同的机制在这里发挥作用:
cut
* 本身 * 是否需要传递给-d
选项的参数(在本例中为空格)作为 * 单独的参数 *,或者是否可以将其 * 直接 * 追加到-d
。(a)是回答了一个报价从POSIX guidelines for utilities(强调地雷)
如果一个标准实用程序的概要显示了一个带有 mandatory option-argument [.]的选项,那么符合要求的应用程序应该为该选项及其option-argument使用 separate arguments。然而,一个一致的实现应该 * 也 * 允许应用程序在同一个参数串中指定选项和选项参数,而不需要插入字符**。
换句话说:在这种情况下,**因为
-d
的option-argument是 mandatory,你可以 * 选择 * 是否指定参数:-d
**的值 *。注意:
cut
的 GNU 实现,默认情况下可以在许多Linux发行版上找到,支持--delimiter
作为-d
的更具描述性的别名。与-d
相同的注意事项,除了直接附加option-argument需要使用=
作为分隔符,而 no 分隔符与-d
一起使用;例如,在一个实施例中,echo 'one two' | cut --delimiter=' ' -f 1
与echo 'one two' | cut -d' ' -f 1
一旦你选择了(s)或(d),那么 shell 的字符串字面量解析-(B)-就很重要了:
-d ' '
-d " "
-d \
(\<space>
是字面上使用的转义空格)-d' '
-d" "
"-d "
'-d '
d\
等价性可以通过 shell 的字符串处理来解释:
以上所有解决方案在
cut
看到它们的时候会产生 * 完全相同的字符串 *(在每组中):*(s):
cut
将-d
视为其 * 自己的 * 参数,后跟一个包含空格字符的 separate 参数-然后不带引号或\
前缀!.*(d):
cut
看到-d
* 加上 * 一个空格字符-然后没有引号或\
前缀!作为“相同”的一部分。各个组中的形式最终相同的原因是双重的,基于**shell* 如何解析 * 字符串字面量 *:
*单引号字符串:
'...'
中的内容按 * 字面 * 理解,并形成 * 单个 * 参数*双引号字符串:
"..."
内部的内容也形成一个 * 单一 * 参数,但受到 * 插值 *(扩展变量引用,如$var
,命令替换($(...)
或...
)或算术扩展($(( ... ))
))的影响。*
\
-引用 * 单个 * 字符:单个字符前的\
会导致该字符被解释为文字。'...'
或"..."
或未加引号的\
示例)-因此,正在调用的命令永远不会看到引号字符。6g8kf2rb4#
你也可以说:
注意反斜杠后面有两个空格。
soat7uwm5#
我刚刚发现你也可以使用
"-d "
:测试
368yc8dk6#
例如,如果数据有多个空格,你就不能很容易地用cut来完成。我发现规范化输入以便于处理是很有用的。一个技巧是使用sed进行规范化,如下所示。
lmvvr0a87#
scut,一个类似cut的实用程序(我做的更聪明但更慢),可以使用任何perl正则表达式作为中断标记。在空白处中断是默认的,但是你也可以在多字符正则表达式、替代正则表达式等处中断。
所以上面的命令会在空白处断开列,并按此顺序提取(从0开始的)字符串6 2 8 7。
xzabzqsa8#
我有一个答案(我承认有点混乱的答案),涉及
sed
,正则表达式和捕获组:\S*
-第一个字\s*
-(\S*)
-第二个字-捕获.*
-线路的其余部分作为
sed
表达式,捕获组需要转义,即\(
和\)
。\1
返回捕获的组的副本,即第二个词。当你看到这个答案时,你可能会想,为什么要这么麻烦呢?好吧,我希望有些人,可能会说“啊哈!“,并将使用此模式来解决一些使用单个
sed
表达式的复杂文本提取问题。