【问题标题】:Selecting the column range in bash using while loop使用while循环在bash中选择列范围
【发布时间】:2020-02-12 01:40:23
【问题描述】:

我有一个名为 text 的文本文件:行和列是:

1   A   18  -180
2   B   19  -180
3   C   20  -150
50  D   21  -100
128 E   22  -130
140  F   23  -0

如果我们想使用 while 循环逐行迭代,那就是:

while read -ra a; do [[ ${a[3]} != -0 ]] && ((a[3]+=42)); echo "${a[@]}"; done < file

输出如下:

1 A 18 -138
2 B 19 -138
3 C 20 -108
50 D 21 -58
128 E 22 -88
140 F 23 -0

上面一行发生的事情是在第 4 列的每一行中添加42,除非有0.

如何使用第一列选择多个列范围?例如,我只想从第一列中选​​择2 to 50,这意味着我只想打印2nd, 3rd and 4th 列。因此输出将是

2 B 19 -138
3 C 20 -108
50 D 21 -58

【问题讨论】:

    标签: bash awk


    【解决方案1】:

    第一种解决方案:如果您只想打印满足条件的行并仅对那些行执行操作,请尝试以下操作。

    awk '$1>=2 && $1<=50{$4+=42;print}'  Input_file
    

    为什么是awk?因为与使用 bash 或任何 shell 循环在这里处理文件相比,它会更快并且是一个明显的选择。



    第二个解决方案:如果 OP 只想在 shell 中做,那么可以尝试跟随。

    while read first second third fourth
    do
       if [[ "$first" -ge 2 && "$first" -le 50 ]]
       then
            echo "$first $second $third $((fourth+42))"
       fi
    done < "Input_file"
    

    上述代码的输出如下:

    2 B 19 -138
    3 C 20 -108
    50 D 21 -58
    

    【讨论】:

    • 到目前为止看起来不错,但我假设 OP 想要将数字添加到第 4 列除非第 4 列的值为零。
    • @tshiono,谢谢你的观点好友。但是 OP 的示例输出没有行 128 E 22 -88 和像 For example, I want to select only 2 to 50 from the first column 这样提到的 OP,所以我想到了这一点。我的英语不是那么好:) 可能是我没有正确理解它吗? :) OP 只能确认这一点。
    • 感谢您的及时回复。我同意你的意见。让我们等待OP的反馈。 BR。
    【解决方案2】:

    Sed 变体

    sed -n "/^2 /,/^50 /p" file
    

    这个 sed 命令意味着打印(p)模式 '^2' 和 '^50' 之间的所有行 包括模式匹配的行,符号'^'代表行的开头。

    或者您可以使用带有sed的大括号扩展

    for i in {2..50}; { sed -n "/^$i /p" file; }
    

    grep

    for i in {2..50}; { grep "^$i " file; }
    

    它很慢,但很容易理解、记住和使用。

    【讨论】:

      猜你喜欢
      • 2023-03-08
      • 2021-09-10
      • 1970-01-01
      • 2011-12-25
      • 2011-11-12
      • 1970-01-01
      • 1970-01-01
      • 2019-11-22
      • 1970-01-01
      相关资源
      最近更新 更多