【问题标题】:Sed or awk: how to call line addresses from separate file?Sed 或 awk:如何从单独的文件中调用线路地址?
【发布时间】:2013-06-11 05:18:14
【问题描述】:

我有(比如说)100 行的“file1”。我想使用 sed 或 awk 将第 23、71 和 84 行(例如)打印到“file2”。这 3 个行号位于单独的文件“列表”中,每个数字位于单独的行中。

当我使用这些命令中的任何一个时,只会打印第 84 行:

for i in $(cat list); do sed -n "${i}p" file1 > file2; done

for i in $(cat list); do awk 'NR==x {print}' x=$i file1 > file2; done

可以以这种方式使用 for 循环为 sed 或 awk 提供行地址吗?

【问题讨论】:

  • 是的,不要!!!请参阅@Jaypal 的答案,了解做你想做的事情的正确方法。
  • @Ed Norton - 我已经尝试了所有建议的解决方案,它们都有效。对于我的特定问题(与我发布的简化问题不同),理想的解决方案是 perreal 的。

标签: sed awk


【解决方案1】:

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

sed 's/.*/&p/' list | sed -nf - file1 >file2

使用list 构建sed 脚本。

【讨论】:

    【解决方案2】:

    您需要在循环之后执行> 才能捕获所有内容。由于您在循环中使用它,因此文件将被覆盖。在循环内你需要做>>

    良好的做法是在循环外使用或使用>,这样文件就不会在每次循环迭代期间打开以供写入。

    但是,您可以在没有for loop 的情况下在awk 中执行所有操作。

    awk 'NR==FNR{a[$1]++;next}FNR in a' list file1 > file2
    

    【讨论】:

    • 谢谢先生。意味着很多来自主人本人。 :)
    【解决方案3】:

    你必须>>(附加到文件)。但是您正在覆盖文件。这就是为什么,你总是只在 file2 中得到 84 行。

    尝试使用,

    for i in $(cat list); do sed -n "${i}p" file1 >> file2; done
    

    【讨论】:

      【解决方案4】:

      使用 sed:

       sed -n $(sed -e 's/^/-e /' -e 's/$/p/' list) input
      

      给定示例输入,内部命令创建如下字符串:`

      -e 23p 
      -e 71p 
      -e 84p 
      

      所以外部 sed 然后打印出给定的行

      【讨论】:

      • 我会改用管道和sed -f -
      • 像这样:sed -e 's/^/-e /' -e 's/$/p/' list | sed -f - -n list
      【解决方案5】:

      您可以避免在 for/while 循环中运行 sed/awk:

      # store all lines numbers in a variable using pipe
      lines=$(echo $(<list) | sed 's/ /|/g')
      
      # print lines of specified line numbers and store output
      awk -v lineS="^($lines)$" 'NR ~ lineS' file1 > out
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-09-12
        • 2023-03-05
        • 2010-10-14
        • 2021-09-14
        • 2015-05-29
        • 2016-02-04
        • 1970-01-01
        相关资源
        最近更新 更多