【问题标题】:Extracting column range from text file via bash tool通过 bash 工具从文本文件中提取列范围
【发布时间】:2017-10-12 03:55:52
【问题描述】:

假设一个文本文件 (file1) 包含多行字母字符串,每行前面都有一个用作条形码的短字母数字字符串。字母字符串的长度都是相同的,前面的字母数字字符串不是。字母和字母数字字符串在每行中用空格分隔。

$ cat file1
a1 abcdefghijklmnopqrstuvwxyz
b27 abcdefghijklmnopqrstuvwxyz
c4 abcdefghijklmnopqrstuvwxyz

假设第二个文件 (file2) 包含有关列范围的信息。此范围始终小于字母字符串。

$ cat file2
2-13

我正在尝试开发 bash 代码,该代码从 file1 中的字母字符串中提取 file2 中指定的列范围,同时保留条形码。

$ sought_command file1 file2
a1 bcdefghijklm
b27 bcdefghijklm
c4 bcdefghijklm

我不确定哪个 bash 电动工具在这方面会有所帮助,但假设 awk 将是可以做到这一点的工具。

注意:我知道 Python 中的代码可能最容易编写有关此任务的代码,我确实这样做了。但是,我发现我的 Python 实现速度非常慢,因为要处理的字母字符串有数万个字符长。因此,我特意尝试使用 bash 工具来解决这个问题。

【问题讨论】:

    标签: string bash awk split multiple-columns


    【解决方案1】:
    $ awk 'NR==FNR{start=$1;lgth=$2;next} {print $1, substr($2,start,lgth)}' FS='-' file2 FS=' ' file1
    a1 bcdefghijklmn
    b27 bcdefghijklmn
    c4 bcdefghijklmn
    

    或者如果第二个字段是结束位置而不是长度:

    $ awk 'NR==FNR{start=$1;lgth=$2-$1+1;next} {print $1, substr($2,start,lgth)}' FS='-' file2 FS=' ' file1
    a1 bcdefghijklm
    b27 bcdefghijklm
    c4 bcdefghijklm
    

    【讨论】:

    • 哇!对我来说,这是最好的 bash 力量。谢谢你的回答。
    • 不客气,谢谢,但这个答案与 bash 无关。它是 awk,一个完全独立的工具,可以从任何 UNIX shell(bash、ksh、csh、sh 等)或 Windows 调用。它恰好是所有 UNIX 安装的标准配置。使用 bash 或任何其他 shell 结构不适合您的问题 - 请参阅 https://unix.stackexchange.com/questions/169716/why-is-using-a-shell-loop-to-process-text-considered-bad-practice
    • 我刚刚意识到您的代码就像file2 的第二个数字是长度,而不是列范围的停止位置。为了纠正这个问题,我尝试将您的命令修改为awk 'NR==FNR{start=$1;lgth=$(expr $2-$1);next} {print $1, substr($2,start,lgth)}' FS='-' file2 FS=' ' file1。见内减法。但是,我的修改不起作用。你有什么建议给我吗?
    • 从您的问题中不清楚 file2 值的含义。您真的需要了解 - awk 不是 bash$((stop-start))$(expr $2-$1) 是 bash 语法,而不是 awk。在 awk 中,要从另一个变量中减去一个变量的值,您只需执行 stop-start。当然,不理会脚本的那部分并制作第一部分NR==FNR{start=$1;lgth=$2-$1+1;next} 会更有效,我已经更新了我的答案以表明这一点。您可以从 Arnold Robbins 的《Effective Awk Programming, 4th Edition》一书中学习 awk。
    • 感谢您的补充回答。现在很清楚了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-23
    • 2012-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-25
    相关资源
    最近更新 更多