假设我有以下文本:
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