6

我有几个具有不同行号的文本文件,我必须在所有这些文件中删除倒数第三行。这是一个示例文件:

bear
horse
window
potato
berry
cup

此文件的预期结果:

bear
horse
window
berry
cup

我们可以删除文件的倒数第三行吗
:不基于任何字符串/模式。
湾。仅基于它必须是倒数第三行的条件

我对如何从最后一行开始索引我的文件有疑问。我已经从倒数第二行的另一个 SO 问题中尝试了这个:

> sed -i 'N;$!P;D' output1.txt
4

4 回答 4

6

ed

ed -s ip.txt <<< $'$-2d\nw'

# thanks Shawn for a more portable solution
printf '%s\n' '$-2d' w | ed -s ip.txt

这将进行就地编辑。$指最后一行,您可以指定一个负的相对值。因此,$-2将参考最后但第二行。w然后命令将写入更改。

有关详细信息,请参阅ed:线路寻址。

于 2020-09-24T13:06:25.967 回答
6

使用tac+awk解决方案,请您尝试以下操作。只需将line变量设置awk为行(从底部),无论您想跳过哪个。

tac Input_file | awk -v line="3" 'line==FNR{next} 1' | tac

说明:使用tac将反向读取 Input_file(从底行到第一行),将其输出传递给awk命令,然后检查条件是否行等于行(我们想跳过)然后不打印该行,1 将打印其他线路。

第二种解决方案:使用awk+wc解决方案,请尝试以下。

awk -v lines="$(wc -l < Input_file)" -v skipLine="3" 'FNR!=(lines-skipLine+1)' Input_file

说明:在此处启动awk程序并创建一个变量lines,其中包含 Input_file 中存在的总行数。变量skipLine具有我们想要从 Input_file 底部跳过的行号。然后在主程序检查条件下,如果当前行不等于lines-skipLine+1然后打印这些行。

第三种解决方案:根据 Ed sir 的评论添加解决方案。

awk -v line=3 '{a[NR]=$0} END{for (i=1;i<=NR;i++) if (i != (NR-line)) print a[i]}' Input_file

说明:为第 3 个解决方案添加详细说明。

awk -v line=3 '             ##Starting awk program from here, setting awk variable line to 3(line which OP wants to skip from bottom)
{
  a[NR]=$0                  ##Creating array a with index of NR and value is current line.
}
END{                        ##Starting END block of this program from here.
  for(i=1;i<=NR;i++){       ##Starting for loop till value of NR here.
    if(i != (NR-line)){     ##Checking condition if i is NOT equal to NR-line then do following.
      print a[i]            ##Printing a with index i here.
    }
  }
}
' Input_file                ##Mentioning Input_file name here.
于 2020-09-24T12:43:33.680 回答
4

这可能对您有用(GNU sed):

sed '1N;N;$!P;D' file

在文件中打开一个包含 3 行的窗口,然后打印/删除窗口的第一行,直到文件结束。

在文件末尾,不要打印窗口中的第一行,即从文件末尾算起的第 3 行。相反,删除它,然后重复 sed 循环。这将尝试在文件末尾附加一行,这将导致 sed 退出,在窗口中打印剩余的行。

向后 n 行的通用解决方案(其中 n 是文件末尾的 2 行或更多行)是:

sed ':a;N:s/[^\n]*/&/3;Ta;$!P;D' file 

当然你可以使用:

tac file | sed 3d | tac

但是,您将阅读该文件 3 次。

于 2020-09-24T15:34:38.640 回答
2

要删除文件的倒数第三行,您可以使用headand tail

{ head -n -3 file; tail -2 file; }

如果输入文件很大,当性能很重要时,这非常快,因为它不会逐行读取和写入。另外,不要修改括号旁边的分号和空格,请参阅关于命令分组


sed使用tac

tac file | sed '3d' | tac

awk使用tac

tac file | awk 'NR!=3' | tac
于 2020-09-24T15:12:40.447 回答