我想知道是否有办法使用wc
和sed
删除文件的一半行。
我可以这样做:
sed -i '50,$d' myfile.txt
这将删除从 50 到文件末尾的行。我也可以这样做:
wc -l myfile.txt
返回文件中的行数。
但我真正想做的是这样的:
wc -l myfile.txt | sed -i '{wc -l result}/2,$d' myfile.txt
- 如何告诉
sed
删除从wc -l
结果除以 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 ... > newFile
或cmd > 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 {}" _ ;