【问题标题】:How do I resolve variables in command line [duplicate]如何在命令行中解析变量[重复]
【发布时间】:2018-10-06 14:44:59
【问题描述】:

我如何获取一个文本文件,跳过前 14 条记录,跳过最后 2 条记录,将其他所有内容放入一个新文件中?

我可以编写一个简单的 Java 或 python 代码来执行此操作,但我正在寻找更简单的 bash 脚本/命令行。

有人可以帮我解决这个问题吗?

【问题讨论】:

标签: bash shell


【解决方案1】:

你可以使用 sed:

lines=$(wc -l < inputfile)                                            
sed -n "15,$((lines-1))p" inputfile > outputfile

【讨论】:

  • 这与所要求的相反;它输出应该跳过的行。
  • 你说得对,我原来的“解决方案”与 OP 想要的相反。我更新了我的答案。
【解决方案2】:

如果您想跳过前 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

希望对你有帮助

【讨论】:

  • 追加到输出文件,而不是从头开始写?
  • @CharlesDuffy 它从第 15 行附加到最后但 2 行。假设 inputfile.txt 中的第 1 2 3 4 5 6 7 8 行,如果前 2 和最后 2 过滤器,则 outfile.txt 包含3 4 5 6 行。
  • 这不起作用;如果 14 k 行之前,您需要知道总共有多少行。
  • @chepner 谢谢,很好,更新了解决方案。
【解决方案3】:

最简单的解决方案是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

【讨论】:

    猜你喜欢
    • 2013-02-15
    • 2015-09-20
    • 1970-01-01
    • 2015-02-28
    • 2011-03-20
    • 1970-01-01
    • 2015-08-10
    • 1970-01-01
    • 2017-03-08
    相关资源
    最近更新 更多