从unix中的倒数第二行删除一个字符

时间:2013-04-03 10:32:08

标签: linux bash unix sed awk

如何在unix中删除文件倒数第二行的字符?

例如,我有一个内容如下的文件:

aaa
bbb*
ccc*
ddd*
eee

我的输出应该是:

aaa
bbb*
ccc*
ddd
eee

有关于此的任何想法吗?

5 个答案:

答案 0 :(得分:5)

使用sed在单次传递中执行此操作的一般方法是使用滑动窗口,类似于GNU sed manual中描述的。

由于您只对第二行到最后一行的替换感兴趣,因此不需要保留空间。在这种情况下,单个N就足够了:

sed 'N; $! { P; D; }; s/.\n/\n/'

或者作为BSD sed兼容脚本:

sed 'N; $! { P; D; }; s/.\n/\
/'

输出:

aaa
bbb*
ccc*
ddd
eee

说明

  • N命令在模式空间中添加第二行。
  • 当我们没有到达最后一行时,将评估$!块。
  • { P; D; }打印第一行模式空间并删除它。如果模式空间不为空,D会产生重启脚本的副作用。
  • 仅当最后两行位于模式空间中时,才会评估替换命令。

答案 1 :(得分:2)

有三种常用方法可供考虑。

使用wc -l file获取行数:

awk 'NR==n-1{sub(/.$/,"")}1' n=$(wc -l file)
aaa
bbb*
ccc*
ddd
eee

解析文件两次:

awk 'FNR==NR{n++;next}FNR==n-1{sub(/.$/,"")}1' file file
aaa
bbb*
ccc*
ddd
eee

在处理前后反转文件:

tac file | sed '2s/.$//' | tac
aaa
bbb*
ccc*
ddd
eee

答案 2 :(得分:2)

一次重复使用ed的好时机:

简短版本:

{ echo '$-1s/.$//' ; echo "w" ; } | ed file_to_modify.txt >/dev/null
带有一些“调试信息”的

版本^^:

{ echo 'doing: $-1s/.$//' >&2 ; echo '$-1s/.$//' ; echo "doing: w" >&2 ; echo "w" ; echo "C" >&2 ; } | ed file_to_modify.txt

简而言之:ed非常接近vi,但一次只能在1行上工作...... 我只是在第n-1行告诉它's /.$//'(用一条线替换最后一个字符)($ =最后一行在ed中,$ -1 =最后一行 - 1)

答案 3 :(得分:1)

使用 vi vim 或任何编辑器打开文件,然后根据需要编辑文件

答案 4 :(得分:0)

用awk直截了当:

awk '{a[NR]=$0}END{for(i=1;i<=NR;i++){if(i==NR-1)sub(/.$/,"",a[i]);print a[i]}}' file
使用awk有点棘手:

awk '{if(f>1)print p;p=l;f++;l=$0}END{sub(/.$/,"",p);print p;print l}' file