如何删除文件中每行的第5个字?


13

我想删除文件中每行的第5个字。

文件的当前内容:

File is not updated or and will be removed  
System will shut down f within 10 seconds  
Please save your work 55 or copy to other location  
Kindly cooperate with us D  

预期产量:

File is not updated and will be removed  
System will shut down within 10 seconds  
Please save your work or copy to other location  
Kindly cooperate with us

Answers:


31

怎么样cut

$ cut -d' ' -f1-4,6- file.txt 
File is not updated and will be removed  
System will shut down within 10 seconds  
Please save your work or copy to other location  
Kindly cooperate with us
  • -d' ' 将分隔符设置为空格

  • -f1-4,6- 选择第一个到第四个字段(单词),保留第5个字段,然后从第6个字段继续打印到其余字段。


11

解决方案cut

cut -d ' ' -f1-4 -f6- FILE

-f是不是在我的支持cut至少(GNU)..
heemayl

在BSD cut中得到了支持,但是我比我更喜欢您的回复。
fd0

1
如果它是GNU剪切的,您将得到--complement标记以简化操作:cut --complement -d ' ' -f5。切记将输出重定向到一个新文件,然后将mv其重定向到原始文件。
Toby Speight 2015年

6

awk:删除第5个字段

awk '{for (i=5; i<NF; i++) $i = $(i+1); NF--};1' file

如果要就地保存文件:https : //stackoverflow.com/q/16529716/7552

您可以删除第5个字段的内容,但是留下2个连续的输出字段分隔符:

awk '{$5 = ""};1' file

需要注意的是,更改awk中任何字段的值都会产生副作用,即重写整个“ $ 0”,每个字段之间只有1个分隔符。如果您想保持对齐,则应考虑在内(除非gnu awk可以避免这种情况?常规awk / nawk将重新计算$ 0)
Olivier Dulac

在这两种情况下,都可以使用单个分隔符重新格式化该行。如果分隔符中有2个空格或空格+ tab,则结果是一个空格。希望对于大多数文本来说都可以。
NeronLeVelu 2015年

4

使用POSIX sed:

sed -e 's/[^[:alnum:]_][[:alnum:]_][[:alnum:]_]*//4' <file

为什么限制类:alnum:和_ 而不是别的什么,然后:blank:还是:space:
NeronLeVelu 2015年

@NeronLeVelu:这取决于您如何定义单词。
cuonglm

@mikeserv; 好赶上!我更新了答案。
cuonglm

什么是\(捕获组\)呢?
mikeserv

@mikeserv:我的输入错误,我只是尝试了一些保留定界符的方法。
cuonglm 2015年

2

glenn提供的解决方案等效于

awk'{$ 5 =“”; 打印}” 文件

正如他和其他人指出的那样,

  1. 从每行中去除前导和尾随空格,
  2. 将每个空格字符串(空格和/或制表符)压缩为单个空格,然后
  3. 在第四个和六个词之间留两个空格。

解决第三个问题的方法是

awk'{$ 5 =“”; 打印}' 文件 | sed's / / /'

这样一来,只要输入五个或更少的单词,在每行的末尾仍会留下一个或多个添加的空格。如果您可以识别一个永远不会出现在输入中的单词,

awk'{$ 5 =“ unicorn”; 打印}' 文件 | sed's / * unicorn //'

甚至可以解决(但仍然会出现问题1和2)。


2
 sed 's/^\(\([[:blank:]]*[^[:blank:]]\{1,\}\)\{4\}\)[[:blank:]]*[^[:blank:]]*/\1/' YourFile > Output.txt
  • 基于空格/制表符分隔符的posix sed(元类[:blank:]])
  • 在第5个字之后保留以下空格,但在第5个字之前保留一个空格

一个更健壮的(sed可能采用最长的模式*,而第一个版本中的模式可能会丢失分隔或单词),但版本会长一些

sed 's/^\([[:blank:]]*\([^[:blank:]]\{1,\}[[:blank:]]\{1,\}\)\{4\}\[^[:blank:]]\{1,\}/\1/' YourFile > Output.txt

1
sed 's/[^[:blank:]]*//5'
mikeserv

@mikeserv,这样可以使周围的分隔符保持sed 's/[[:blank:]*[^[:blank:]]*//5'更好。很好的一点。我怀疑sed将每个字符当作一个实体,但它采用的是最大的不间断模式作为实体
NeronLeVelu

sed 's/[[:blank:]][^[:blank:]]*//4'将完全删除第5个字段。
mikeserv

@mikeserv假设线路上没有起始空间(如示例中所示)
NeronLeVelu

在这种情况下,是的,我认为您是对的。通常,这样的事情将是一个字段,并且行为将是正确的。在这种情况下,你应该做的@cuonglm没有和确保你引用一个字每一次一样sed 's/[[:blank:]][^[:blank:]][^[:blank:]]*//4',或者,W / GNU / BSD / toybox sedS: sed -E 's/[[:blank:]][^[:blank:]]+//4'
mikeserv

1

Perl。

perl -ne 'print $_ =~ /^(\w+ +\w+ +\w+ +\w+ +)\w+ (.*)/,"\n"' file

1

假设GNU削减了另一种可能性:

cut -d' ' -f5 --complement file.txt

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.