使用 sed 和 wc 递归删除一半的文件行



我想知道是否有办法使用wcsed删除文件的一半行。

我可以这样做:

sed -i '50,$d' myfile.txt

这将删除从 50 到文件末尾的行。我也可以这样做:

wc -l myfile.txt

返回文件中的行数。

但我真正想做的是这样的:

wc -l myfile.txt | sed -i '{wc -l result}/2,$d' myfile.txt
  1. 如何告诉sed删除从wc -l结果除以 2 开始的行?
  2. 如何递归执行此操作?

您可以使用head命令:

head -n -"$(($(wc -l<file)/2))" file

awk 也是可能的,并且使用exit语句,它可以更快:

awk -v t="$(wc -l <file)" 'NR>=t/2{exit}7' file

可以通过awk/head ... > newFilecmd > tmp && mv tmp file获取文件以进行"就地"更改。

我想你很接近。只需使用带有算术扩展的命令替换即可获取起始行的值:

startline="$(( $(wc -l <myfile.txt) / 2 ))"
sed -i "$startline"',$d' myfile.txt

或单行:

sed -i "$(( $(wc -l <myfile.txt) / 2 ))"',$d' myfile.txt

从某种意义上说,读取文件两次(或者,正如肯特所指出的,一次半(是不可避免的。如果您只使用单个进程,也许效率会稍微高一些

awk 'NR==FNR { total=FNR; next }
FNR>total/2 { exit } 1' myfile.txt myfile.txt

使用 Awk 递归执行此操作有点痛苦。如果你有GNU Awk,你可以使用-t inline选项,但是当你两次读取同一个文件时,我不确定它的语义。也许只是回退到临时输出文件。

find . -type f -exec sh -c "awk 'NR==FNR { total=FNR; next }
FNR>total/2 { exit } 1' {} {} >tmp &&
mv tmp {}" _ ;

最新更新