如何使用 sed 删除文件的最后 n 行



我想从文件末尾删除一些n行。这可以使用 sed 完成吗?

例如,要删除从 2 到 4 的行,我可以使用

$ sed '2,4d' file

但我不知道行号。 我可以使用

$sed $d file

但我想知道从末尾删除 n 行的方法。请让我知道如何使用 sed 或其他方法做到这一点。

我不知道

sed,但可以用head来完成:

head -n -2 myfile.txt

如果可以选择硬编码 n,则可以对 sed 使用顺序调用。例如,要删除最后三行,请删除最后一行三次:

sed '$d' file | sed '$d' | sed '$d'

从 sed 单行:

# delete the last 10 lines of a file
sed -e :a -e '$d;N;2,10ba' -e 'P;D'   # method 1
sed -n -e :a -e '1,10!{P;N;D;};N;ba'  # method 2

似乎是你要找的。

使用

sed ,但让 shell 进行数学运算,目标是通过给出一个范围来使用 d 命令(删除最后 23 行):

sed -i "$(($(wc -l < file)-22)),$d" file

要从内到外删除最后 3 行:

$(wc -l < file)

给出文件的行数:比如 2196

我们要删除最后 23 行,因此对于左侧或范围:

$((2196-22))

给予: 2174因此,原始的 sed 后壳解释是:

sed -i '2174,$d' file

随着-i进行就地编辑,文件现在是 2173 行!

如果要将其保存到新文件中,代码为:

sed -i '2174,$d' file > outputfile

一个有趣而简单的sedtac解决方案:

n=4
tac file.txt | sed "1,$n{d}" | tac

注意

  • 外壳需要双引号 "才能计算 sed 命令中的$n变量。在单引号中,不会执行插值。
  • tac是反转cat,请参见man 1 tac
  • sed 中的{}用于分离 $nd(如果没有,shell 会尝试插入不存在的$nd变量)

你可以用来做这件事。

$ head --lines=-N file > new_file

其中 N 是要从文件中删除的行数。

原始文件的内容减去最后 N 行现在为new_file

为了完整起见,我想添加我的解决方案。我最终用标准ed这样做:

ed -s sometextfile <<< $'-2,$dnwq'

这会使用就地编辑删除最后 2 行(尽管它确实/tmp 中使用了临时文件!!

要真正就地截断非常大的文件,我们有truncate命令。它不知道行,但tail + wc可以将行转换为字节:

file=bigone.log
lines=3
truncate -s -$(tail -$lines $file | wc -c) $file

如果同时写入文件,则存在明显的争用条件。在这种情况下,最好使用 head - 它从文件开头(思维磁盘 IO)开始计算字节数,因此我们将始终在行边界上截断(如果文件主动写入,则可能比预期更多的行):

truncate -s $(head -n -$lines $file | wc -c) $file

方便的单行,如果您登录失败尝试将密码代替用户名:

truncate -s $(head -n -5 /var/log/secure | wc -c) /var/log/secure

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

sed ':a;$!N;1,4ba;P;$d;D' file

上面的大多数答案似乎都需要GNU命令/扩展:

    $ head -n -2 myfile.txt
    -2: Badly formed number

对于稍微便携一点的解决方案:

     perl -ne 'push(@fifo,$_);print shift(@fifo) if @fifo > 10;'

     perl -ne 'push(@buf,$_);END{print @buf[0 ... $#buf-10]}'

     awk '{buf[NR-1]=$0;}END{ for ( i=0; i < (NR-10); i++){ print buf[i];} }'

其中"10"是"n"。

有了这里的答案,您已经了解到 sed 不是此应用程序的最佳工具。

但是,我确实认为在使用sed时有一种方法可以做到这一点; 这个想法是附加N行来保持空间,直到您能够在不点击EOF的情况下阅读。 当命中EOF时,打印保留空间的内容并退出。

sed -e '$!{N;N;N;N;N;N;H;}' -e x

上面的 sed 命令将省略最后 5 行。

它可以通过 3 个步骤完成:

a) 计算要编辑的文件中的行数:

 n=`cat myfile |wc -l`

b) 从该数字中减去要删除的行数:

 x=$((n-3))

c) 告诉 sed 从该行号 ( $x ) 中删除到最后:

 sed "$x,$d" myfile

您可以使用 wc -l <file> 和 use 获取行总数

head -n <total lines - lines to remove> <file>

尝试以下命令:

n = line number
tail -r file_name | sed '1,nd' | tail -r

这将从file中删除最后 3 行:

for i in $(seq 1 3); do sed -i '$d' file; done;

我更喜欢这个解决方案;

head -$(gcalctool -s $(cat file | wc -l)-N) file

其中 N 是要删除的行数。

sed -n ':pre
1,4 {N;b pre
    }
:cycle
$!{P;N;D;b cycle
  }' YourFile

波西斯版本

删除最后 4 行:

$ nl -b a file | sort -k1,1nr | sed '1, 4 d' | sort -k1,1n | sed 's/^ *[0-9]*t//'   
我想

出了这个,其中 n 是您要删除的行数:

count=`wc -l file`
lines=`expr "$count" - n`
head -n "$lines" file > temp.txt
mv temp.txt file
rm -f temp.txt

这有点迂回,但我认为很容易遵循。

  1. 计算主文件中的行数
  2. 计数中减去要删除的行数
  3. 打印出要保留并存储在临时文件中的行数
  4. 主文件替换为临时文件
  5. 删除临时文件
#!/bin/sh
echo 'Enter the file name : '
read filename
echo 'Enter the number of lines from the end that needs to be deleted :'
read n
#Subtracting from the line number to get the nth line
m=`expr $n - 1`
# Calculate length of the file
len=`cat $filename|wc -l`
#Calculate the lines that must remain
lennew=`expr $len - $m`
sed "$lennew,$ d" $filename

一种类似于 https://stackoverflow.com/a/24298204/1221137 的解决方案,但要就地编辑,而不是硬编码的行数:

n=4
seq $n | xargs -i sed -i -e '$d' my_file

在 docker 中,这对我有用:

head --lines=-N file_path > file_path

假设您有几行:

    $ cat <<EOF > 20lines.txt
> 1
> 2
> 3
[snip]
> 18
> 19
> 20
> EOF

然后你可以抓住:

# leave last 15 out
$ head -n5 20lines.txt
1
2
3
4
5
# skip first 14
$ tail -n +15 20lines.txt
15
16
17
18
19
20

使用ex/vi的POSIX兼容解决方案,与上述@Michel的解决方案一致。@Michel ed示例使用"not-POSIX"Here-Strings。递增$-1以将n行删除到 EOF ($),或者只馈送您想要 (d) elete 的行。你可以使用ex来计算行号或做任何其他Unix的事情。

给定文件:

cat > sometextfile <<EOF
one
two
three
four
five
EOF

执行:

ex -s sometextfile <<'EOF'
$-1,$d
%p
wq!
EOF

返回:

one
two
three
这使用 POSIX

Here-Docs,因此修改起来非常容易 - 尤其是使用带有 POSIX /bin/shset -o vi 。在主题上,"vim"的"前人格"应该没问题,但是 YMMV。

要删除文件的最后 N 行,您可以使用相同的概念

$ sed '2,4d' file

您可以使用带有尾巴的组合命令来反转文件:如果 N 为 5

$ tail -r file | sed '1,5d' file | tail -r > file

这种方式也可以在命令不运行的地方运行head -n -5 file(就像在 mac 上一样!

这将删除最后 12 行

sed -n -e :a -e '1,10!{P;N;D;};N;ba'

相关内容

  • 没有找到相关文章

最新更新