如何编辑文件中的最后n行?


10

有没有可以让我编辑文件中最后n行的命令?我有几个文件,里面都有不同数量的行。但是我想修改每个文件的最后n行。目标是在最后n行中用分号替换逗号。但仅在最后n行中。

我不想删除任何行,我只想在每个文件的最后n行中用分号替换每个逗号。

使用sed命令,我可以用此命令替换最后一行。如此处所述: 如何删除文件最后一行的文本?

但这仅使我能够修改最后一行,而不是最后n行。


1
只需用sed '24,$s/,/:/g' filename 其中24的起始line`
瓦伦丁巴伊拉米

Answers:


13

将最后n行的逗号替换为分号ed

n=3
ed -s input <<< '$-'$((n-1))$',$s/,/;/g\nwq'

分开:

  • ed -s =静默运行ed(不报告最后写入的字节)
  • '$-'=从文件末尾($)减...
  • $((n-1)) = n-1行...
  • $' ... '=引用命令的其余部分以保护它不受外壳影响)
  • ,$s/,/;/g= ...直到文件(,$)末尾,搜索并用分号替换所有逗号。
  • \nwq =结束上一条命令,然后保存并退出

将最后n行的逗号替换为分号sed

n=3
sed -i "$(( $(wc -l < input) - n + 1)),\$s/,/;/g" input

分开:

  • -i =编辑文件“就地”
  • $(( ... )) =做一些数学运算:
  • $( wc -l < input) =获取文件中的行数
  • -n + 1 =向后退n-1行
  • ,\$ =从n-1行到文件结尾:
  • s/,/;/g =用分号替换逗号。

可以替换wc -l < inputwc -l input。应该快几纳秒:)
gardenhead

1
除了也wc -l input输出文件名之外;我们只想要行数
Jeff Schaller

ed的第一个建议是简单明了。
sku2003 '17

实际上,我最终得到了完全不同的帮助。这导致了这段奇怪的代码,虽然可以解决问题,但是又长又奇怪。我猜想这是您在组合解决方案时可能会遇到的一些奇怪的事情。无论如何,您的代码比我的代码更漂亮,更短,更简单:此处的代码也有效:
sku2003

cat input.file | sed's /,/,\ n / g'| sed -n'1!G; h; $ p'| awk -vn = 2'NR <= n {gsub(“,”,“;”,$ 0)} {print}'| sed -n'1!G; h; $ p'| sed'/ ^ \ s * $ / d'> output.file
sku2003 '17

6

使用tacsed的解决方案在file.txt的最后50行中用分号替换每个逗号:

tac file.txt | sed '1,50s/,/;/g' | tac

5

使用GNU head和类似Bourne的外壳:

n=20
{ head -n -"$n"; tr , ';'; } < file 1<> file

我们正在覆盖文件本身。这是确定这里一个字节到字节的音译,但不一定会如果修改意味着改变文件的大小(在这种情况下,你要替换1<> file> other-file && mv other-file file的实例)。


1
这是的文档1<>,我不熟悉。此外,spongemoreutils是要覆盖您的输入管道的好工具。
迈尔斯

1

假设我们要用7Shell脚本和GNU实现替换以下序列的最后几行sed

$ seq 20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

步骤1:让我们获得序列的最后一行编号,如下所示。看看这个那个

$ lastLine=`seq 20|sed -n '$='`

$ echo $lastLine 
20

步骤2:让我们设置要编辑的行数(在序列末尾):

$ numberOfLines=7

$ echo $numberOfLines 
7

步骤3:让我们根据之前的变量来计算起始行,如下所示。看一下这个

$ startLine=`expr $lastLine - $numberOfLines + 1`

$ echo $startLine 
14

步骤4:现在,我们可以将序列的最后7行替换为其他内容,如下所示。看一下这个

$ seq 20|sed -e "$startLine,+$numberOfLines{s/[12]/WoW/}"
1
2
3
4
5
6
7
8
9
10
11
12
13
WoW4
WoW5
WoW6
WoW7
WoW8
WoW9
WoW0

步骤4使用sed手册页的第4.4节,其中说:

'ADDR1,+N'
     Matches ADDR1 and the N lines following ADDR1.

第4步,也使用双引号提到这里


好吧,如果我们这样使用Gohu答案,那么这四个步骤是不必要的:

$ seq 20 |tac|sed -e '1,7{s/[12]/WoW/}'|tac
1
2
3
4
5
6
7
8
9
10
11
12
13
WoW4
WoW5
WoW6
WoW7
WoW8
WoW9
WoW0

0

使用tail并通过管道进行镇静:

tail -n 20 file | sed 's/,/;/g'

这适用于文件的最后20行。如果要让您直接找到文件,请使用:

tail -n 20 file | sed -i 's/,/;/g'

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.