编辑匹配模式后的行

编辑匹配模式后的行

假设我有以下文本:

file.txt 4 minutes 11 seconds 102 msec
file_1.txt 5 minutes 10 seconds 100 msec
file_3_2.txt 0 minutes 10 seconds 100 msec

如何使用 删除所有单词,同时保留数字和文件名sed

file.txt 4 11 102
file_1.txt 5 10 100
file_3_2.txt 0 10 100

答案1

有多种方法可以提取您所需的数据。

如果您将每一行视为由空格分隔的多个字段,那么您可以用来解决问题的最基本工具是cut

$ cut -d ' ' -f 1,2,4,6 file
file.txt 4 11 102
file_1.txt 5 10 100
file_3_2.txt 0 10 100

这将从文件中提取第 1 个、第 2 个、第 4 个和第 6 个空格分隔字段。

同样,与awk

$ awk '{ print $1,$2,$4,$6 }' file
file.txt 4 11 102
file_1.txt 5 10 100
file_3_2.txt 0 10 100

这是在做同样的事情,但还有更多的内容。该awk工具将其输入视为流记录由组成领域。默认情况下,记录只是一行,字段是由空格(空格或制表符,可能多个)分隔的任何非空白文本。创建输出,一次一个记录(默认情况下,一次一行),并且字段之间用一个空格分隔。


稍微复杂一点的方法是从其余数据中剪切第一个字段,删除其余数据中的任何字母,然后再次将两者粘贴在一起。

$ paste -d ' ' \
    <( cut -d ' ' -f 1  file ) \
    <( cut -d ' ' -f 2- file | tr -s '[:alpha:]' '[ *]' )
file.txt 4 11 102
file_1.txt 5 10 100
file_3_2.txt 0 10 100

但这有点不优雅,因为它读取输入两次。使用的命令tr会将所有字母字符更改为空格,然后将-s任何一组多个连续空格“压缩”(使用 )为单个空格。

paste命令获取两个输入流,并将它们逐行连接起来,中间有一个空格字符。第一个流是通过<( ... )运行cut命令的进程替换 ( ) 提供的,该命令仅从数据中提取第一列。第二个流由另一个进程替换提供,该进程替换运行cut以提取第 2 列上的所有列,然后tr如前所述使用这些列中的空格替换字母字符。

答案2

目前还不清楚你的例子对你的问题有多具体。假设这确实是您所要求的(这让我担心这可能是课堂练习),那么您可以利用这样一个事实:您只有 3 个已知字符串需要删除,并且您希望最终符号之间只有单个空格创建一个非常短的 sed 命令。此示例使用 MacOS 提供的 BSD sed,输入位于文件 input.txt 中,输出位于 stdout。

sed -E -e 's/ (minutes|seconds|msec)//g' < input.txt

这将匹配单个空格,后跟目标字符串之一,然后将其替换为空。末尾的“g”表示重复应用到同一行。

答案3

您的问题可以通过以下 GNU sed 命令来解决:

$ sed -Ee ' /(\s+\S+)\s+\S+/\1/g' file

我们不断交替空格-单词并拒绝下一个空格-单词组合。

答案4

一种解决方案是删除所有“一个空格”后跟“非数字单词”:

$ sed -E 's/ \<[^0-9]*\>//g' file
file.txt 4 11 102
file_1.txt 5 10 100
file_3_2.txt 0 10 100

相关内容