【发布时间】:2018-10-06 14:44:59
【问题描述】:
我如何获取一个文本文件,跳过前 14 条记录,跳过最后 2 条记录,将其他所有内容放入一个新文件中?
我可以编写一个简单的 Java 或 python 代码来执行此操作,但我正在寻找更简单的 bash 脚本/命令行。
有人可以帮我解决这个问题吗?
【问题讨论】:
-
看头尾,还是sed
-
14 records是什么意思?它们与休息有何不同?
我如何获取一个文本文件,跳过前 14 条记录,跳过最后 2 条记录,将其他所有内容放入一个新文件中?
我可以编写一个简单的 Java 或 python 代码来执行此操作,但我正在寻找更简单的 bash 脚本/命令行。
有人可以帮我解决这个问题吗?
【问题讨论】:
14 records 是什么意思?它们与休息有何不同?
你可以使用 sed:
lines=$(wc -l < inputfile)
sed -n "15,$((lines-1))p" inputfile > outputfile
【讨论】:
如果您想跳过前 N(14) 行和最后 M(2) 行,可以使用 awk 来完成
#!/bin/bash
awk -v N="$(wc -l < inputfile.txt)" -v first_lines=14 -v last_lines=2 '{
if (NR >= first_lines && NR <= N - last_lines)
print $0
}' inputfile.txt >> outfile.txt 2>&1
希望对你有帮助
【讨论】:
最简单的解决方案是head 和tail 的组合:
# hf_filter - remove a header and footer of fixed length from the input
$ hf_filter () { tail -n +$(($1 + 1)) | head -n -$2; }
$ hf_filter 14 2 < old.txt > new.txt
但是,这需要 GNU head,因为标准版本需要正整数作为 -n 选项的参数。
此问题的解决方案需要缓冲$last 输出行或输入长度的先验知识。 (GNU head 为你做缓冲。)标准的 awk 解决方案可能看起来像
awk -v h=14 -v t=2 'NR > h {buf[NR]=$0; s=NR-t} s in buf {print buf[s]; delete buf[s]}' old.txt > new.txt
delete buf[s] 不是绝对必要的,但我认为它应该保持内存使用量不变(虽然我真的不知道awk 如何在内部管理内存分配)。
如果你不介意读两次输入,如果你还不知道输入长度,你可以得到它。
# Quotes are necessary; wc outputs leading spaces that break the assignment otherwise
awk -v n="$(wc -l < old.txt)" h=14 t=2 'NR > h && NR < n - t' old.txt > new.txt
【讨论】: