我试图从基于列的、“空间”调整的文本流中提取特定的(第四个)字段。我尝试以以下方式使用cut命令:cat text.txt | cut -d " " -f 4个不幸的是,cut不将多个空格视为一个分隔符。我本可以通过awkawk '{ printf $4; }'个或sedsed -E "s/[[:space:]]+/ /g"个折叠空格,但我想知道是否有任何方法来处理cut和几个分隔符本机?
cut
cat text.txt | cut -d " " -f 4
awk '{ printf $4; }'
sed -E "s/[[:space:]]+/ /g"
uubf1zoe1#
试试看:
tr -s ' ' <text.txt | cut -d ' ' -f4
字符串来自tr手册页:
tr
-s, --squeeze-repeats replace each input sequence of a repeated character that is listed in SET1 with a single occurrence of that character
型
rryofs0p2#
正如你在问题中所评论的那样,awk确实是一条路要走。使用cut和tr -s可以压缩空间,如kev's answer所示。不过,让我为未来的读者介绍一下所有可能的组合。说明见测试章节。
awk
tr -s
tr -s ' ' < file | cut -d' ' -f4
字符串
awk '{print $4}' file
while read -r _ _ _ myfield _ do echo "forth field: $myfield" done < file
sed -r 's/^([^ ]*[ ]*){3}([^ ]*).*/\2/' file
给定这个文件,让我们测试命令:
$ cat a this is line 1 more text this is line 2 more text this is line 3 more text this is line 4 more text
$ cut -d' ' -f4 a is # it does not show what we want! $ tr -s ' ' < a | cut -d' ' -f4 1 2 # this makes it! 3 4 $
$ awk '{print $4}' a 1 2 3 4
这将顺序读取字段。通过使用_,我们指出这是一个一次性变量,作为一个忽略这些字段的“垃圾变量”。这样,我们将$myfield存储为文件中的第4个字段,无论它们之间的空格是多少。
_
$myfield
$ while read -r _ _ _ a _; do echo "4th field: $a"; done < a 4th field: 1 4th field: 2 4th field: 3 4th field: 4
这将捕获三组空格,并且没有包含([^ ]*[ ]*){3}的空格。然后,它捕捉到直到空格作为第四个字段的任何内容,最终打印为\1。
([^ ]*[ ]*){3}
\1
$ sed -r 's/^([^ ]*[ ]*){3}([^ ]*).*/\2/' a 1 2 3 4
vohkndzv3#
在对cut的太多限制感到沮丧之后,我编写了自己的替代品,我称之为cuts,意思是“类固醇上的削减”。cuts提供了可能是最简单的解决方案,以解决这个问题和 * 许多其他 * 相关的剪切/粘贴问题。在众多例子中,有一个是针对这个问题的:
cuts
$ cat text.txt 0 1 2 3 0 1 2 3 4 $ cuts 2 text.txt 2 2
字符串cuts支持:
paste
还有更多这些都不是标准cut提供的。标签:https://stackoverflow.com/a/24543231/1296044源代码和文档(自由软件):***http://arielf.github.io/cuts/***的
0x6upsns4#
这个Perl单行程序显示了Perl与awk的关系有多密切:
perl -lane 'print $F[3]' text.txt
字符串但是,@F autossplit数组以索引$F[0]开始,而awk字段以$1开始
@F
$F[0]
$1
enyaitl35#
对于我所知的cut版本,不,这是不可能的。cut主要用于解析分隔符不是空白的文件(例如/etc/passwd),并且具有固定数目字段的文件。一行中的两个分隔符表示一个空字段,这也适用于空白。
/etc/passwd
41ik7eoe6#
我创建了a patch,它为cut添加了新的-m命令行选项,它在字段模式下工作,并将多个连续的分隔符视为单个分隔符。这基本上以一种相当有效的方式解决了OP的问题。几天前我还向上游提交了这个补丁,希望它能被合并到coreutils项目中。有一些关于在cut中添加更多与空白相关的特性的further thoughts,并对所有这些都有一些反馈会很好。我愿意为cut实现更多的补丁并将它们提交到上游,这将使这个实用程序在各种现实场景中更加通用和可用。
-m
6条答案
按热度按时间uubf1zoe1#
试试看:
字符串
来自
tr
手册页:型
rryofs0p2#
正如你在问题中所评论的那样,
awk
确实是一条路要走。使用cut
和tr -s
可以压缩空间,如kev's answer所示。不过,让我为未来的读者介绍一下所有可能的组合。说明见测试章节。
tr|切割
字符串
awk
型
bash
型
sed
型
测试
给定这个文件,让我们测试命令:
型
tr|切割
型
awk
型
bash
这将顺序读取字段。通过使用
_
,我们指出这是一个一次性变量,作为一个忽略这些字段的“垃圾变量”。这样,我们将$myfield
存储为文件中的第4个字段,无论它们之间的空格是多少。型
sed
这将捕获三组空格,并且没有包含
([^ ]*[ ]*){3}
的空格。然后,它捕捉到直到空格作为第四个字段的任何内容,最终打印为\1
。型
vohkndzv3#
最短/最友好的解决方案
在对
cut
的太多限制感到沮丧之后,我编写了自己的替代品,我称之为cuts
,意思是“类固醇上的削减”。cuts提供了可能是最简单的解决方案,以解决这个问题和 * 许多其他 * 相关的剪切/粘贴问题。
在众多例子中,有一个是针对这个问题的:
字符串
cuts
支持:paste
)还有更多这些都不是标准
cut
提供的。标签:https://stackoverflow.com/a/24543231/1296044
源代码和文档(自由软件):***http://arielf.github.io/cuts/***的
0x6upsns4#
这个Perl单行程序显示了Perl与awk的关系有多密切:
字符串
但是,
@F
autossplit数组以索引$F[0]
开始,而awk字段以$1
开始enyaitl35#
对于我所知的
cut
版本,不,这是不可能的。cut
主要用于解析分隔符不是空白的文件(例如/etc/passwd
),并且具有固定数目字段的文件。一行中的两个分隔符表示一个空字段,这也适用于空白。41ik7eoe6#
我创建了a patch,它为
cut
添加了新的-m
命令行选项,它在字段模式下工作,并将多个连续的分隔符视为单个分隔符。这基本上以一种相当有效的方式解决了OP的问题。几天前我还向上游提交了这个补丁,希望它能被合并到coreutils项目中。有一些关于在
cut
中添加更多与空白相关的特性的further thoughts,并对所有这些都有一些反馈会很好。我愿意为cut
实现更多的补丁并将它们提交到上游,这将使这个实用程序在各种现实场景中更加通用和可用。