【问题标题】:Adding content before specific line number(s) in a text file using Shell Scripting使用 Shell 脚本在文本文件中的特定行号之前添加内容
【发布时间】:2021-11-22 08:28:33
【问题描述】:

所以我有一个看起来像这样的文本文件:

a1
b1
c1 
a2 
b2 
c2
.
.
.

现在我想索引这个文本文件的每个组件,如下所示:

0:
a1
b1
c1
1:
a2
b2
c2
.
.
.

我尝试开发了几个 shell 脚本,但遗憾的是无法实现上述目标。如果有人可以为我指出如何使用 shell 脚本执行上述任务的正确方向,那就太好了。谢谢!

PS:我是 macOS 用户(请注意,因为 awk/sed 命令在 macOS 和 Linux 上的执行方式略有不同)

【问题讨论】:

  • 如何识别新组件的开始位置?还是行号已知?

标签: shell awk sed grep


【解决方案1】:
$ cat input
a1
b1
c1
a2
b2
c2
.
.
.
$ awk '/^a/{printf "%d:\n", counter++}1' input
0:
a1
b1
c1
1:
a2
b2
c2
.
.
.

或者:

awk '/^a/{print counter++ ":" }1' input,但printf 感觉更干净。

【讨论】:

    【解决方案2】:

    使用这个 Perl 单行,它依赖于每个组恰好有 3 行共享相同索引的假设:

    echo 'a1 b1 c1 a2 b2 c2 a3 b3 c3' | xargs -n1 > in_file
    perl -lpe '$i = (($. - 1) / 3); print "$i:" if ! (($. - 1) % 3);' in_file > out_file
    

    out_file的内容:

    0:
    a1
    b1
    c1
    1:
    a2
    b2
    c2
    2:
    a3
    b3
    c3
    

    Perl 单行代码使用这些命令行标志:
    -e:告诉 Perl 查找内联代码,而不是在文件中。
    -p:循环输入一行一次,默认分配给$_。在每次循环迭代后添加print $_
    -l:在执行内联代码之前去除输入行分隔符(默认情况下 *NIX 上为"\n"),并在打印时附加它。

    $.:当前输入行号。

    另请参阅:
    perldoc perlrun: how to execute the Perl interpreter: command line switches

    【讨论】:

      【解决方案3】:

      在每个 Unix 机器上的任何 shell 中使用任何 awk:

      $ awk '{key=$0; gsub(/[^0-9]+/,"",key)} key != prev{print (key-1)":"} {print; prev=key}' file
      0:
      a1
      b1
      c1
      1:
      a2
      b2
      c2
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-05-21
        • 2019-05-04
        • 2023-04-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多