【问题标题】:get string from lines of file in bash从bash中的文件行获取字符串
【发布时间】:2016-09-12 01:15:32
【问题描述】:

我在文件中有这些行:

postgres  2609 21030  0 12:49 ?        00:00:00 postgres: postgres postgres [local] idle in transaction                                                                     
postgres  2758 21030  0 12:51 ?        00:00:00 postgres: postgres postgres [local] idle in transaction                                                                     
postgres 28811 21030  0 09:26 ?        00:00:00 postgres: postgres postgres [local] idle in transaction                                                                     
postgres 32200 21030  0 11:40 ?        00:00:00 postgres: postgres postgres [local] idle in transaction                                                                     
postgres 32252 21030  0 11:41 ?        00:00:00 postgres: postgres postgres [local] idle in transaction                                                                     

我需要分开第二列的值来处理它们。我已经完成了这段代码:

pid=$(cat idle_log.txt | cut -d" " -f2)
echo $pid

但它只在结果中给了我 28811 32200 32252。如您所见,列表中没有 2609 2758 的痕迹,我也想得到它们。 我也想在提取 pid 后对它们进行计数。 我用过:

npid=$(grep -o " " <<< $pid | grep -c .)

它为 28811 32200 32252 的结果返回 2 我需要它返回 3 作为进程计数。 最后我想用while循环处理一些事情,但是命令输出一次返回结果,我不能以循环格式一个一个地处理它们。

谢谢大家的帮助。

【问题讨论】:

标签: linux bash ubuntu grep cut


【解决方案1】:

您可以使用tr 压缩空格,然后使用cut 获取第二个空格分隔字段:

tr -s ' ' <idle_log.txt | cut -d' ' -f2

awk:

awk '{ print $2 }' idle_log.txt

sed:

sed -r 's/^[^[:blank:]]+[[:blank:]]+([^[:blank:]]+)(.*)/\1/' idle_log.txt

grep:

grep -Po '^[^\s]+\s+\K[^\s]+' idle_log.txt

要在以后使用/计算它们,请使用数组:

pids=( $(tr -s ' ' <idle_log.txt | cut -d' ' -f2) )

num_of_pids="${#pids[@]}"

$ printf '%s\n' "${pids[@]}" 
2609
2758
28811
32200
32252

示例:

$ tr -s ' ' <file.txt | cut -d' ' -f2 
2609
2758
28811
32200
32252

$ awk '{ print $2 }' file.txt        
2609
2758
28811
32200
32252

$ sed -r 's/^[^[:blank:]]+[[:blank:]]+([^[:blank:]]+)(.*)/\1/' file.txt
2609
2758
28811
32200
32252

$ grep -Po '^[^\s]+\s+\K[^\s]+' file.txt
2609
2758
28811
32200
32252

【讨论】:

  • 嗯,不错的技巧,但我仍然需要每次都得到一个值。
  • 感谢您抽出宝贵时间,我刚刚使用了与我的情况更接近的第一个答案。
【解决方案2】:
$ cat data 
postgres  2609 21030  0 12:49 ?        00:00:00 postgres: postgres postgres [local] idle in transaction
postgres  2758 21030  0 12:51 ?        00:00:00 postgres: postgres postgres [local] idle in transaction
postgres 28811 21030  0 09:26 ?        00:00:00 postgres: postgres postgres [local] idle in transaction
postgres 32200 21030  0 11:40 ?        00:00:00 postgres: postgres postgres [local] idle in transaction
postgres 32252 21030  0 11:41 ?        00:00:00 postgres: postgres postgres [local] idle in transaction   I need to extract second column from each line, 
$ awk '{print $2}' data 
2609
2758
28811
32200
32252

或者您可以使用tr 将多个空格压缩为1,然后像这样使用cut

$ tr -s ' ' < data | cut -d ' ' -f 2
2609
2758
28811
32200
32252

编辑:

$ tr -s ' ' < data | cut -d ' ' -f 2 | while read -r line || [[ -n "$line" ]]; do
> echo "$line" #put your custom processing logic here
> done
2609
2758
28811
32200
32252

【讨论】:

  • 谢谢,你知道不要一次输出吗?我需要逐行读取值。 . .
  • 我想计算交易过程中空闲的经过时间,如果它们超过了五分钟,我应该给它的所有者发送邮件来检查它。
  • @Ali_T 是的,你可以在我用过echo ..的地方写下那个逻辑@
  • 只是一件事我想将“tr . . .”结果作为“pid”传递给变量以获取经过的时间,但同时与它流水线化......任何想法?
  • @Ali_T 如果你存储在一个名为 pid 的变量中,你将不得不在该变量 pid 上使用 while 循环而不是上述格式
【解决方案3】:

使用 Perl 正则表达式 grep:

grep -oP '^[\S]+\s+\K[\S]+' file
2609
2758
28811
32200
32252

或者,

grep -o '^\([^[:blank:]]*[[:blank:]]*\)\{2\}' file |grep -o '[0-9]\+'
2609
2758
28811
32200
32252

【讨论】:

    【解决方案4】:

    cut 完全使用您传递的分隔符。这意味着使用分隔符' ',第一行是:

    postgres, <empty>, 2609
    

    最后一个是:

    postgres, 32252
    

    您可以通过运行 awk '{print $2}' idle_log.txt 来简化此操作

    【讨论】:

      【解决方案5】:

      我会选择最简单的解决方案:

      pid=$(awk '{print $2}' idle_log.txt)
      echo $pid
      

      sed 和 grep 的正则表达式在脚本中的可读性要低得多,而 cut 和 tr 有时可能会产生意想不到的结果。

      【讨论】:

        【解决方案6】:

        正如已经指出的那样,你没有得到的原因是你没有提取第二列。

        相反,您使用的是命令cut -d" " -f2,因此您获得了每行的第二个表空间拆分。您可能会看到前两行有一个额外的表空间,因此您应该使用cut -d" " -f3,但正如所讨论的,这不是获取第二列的正确方法。请改用awk '{print $2}'

        【讨论】:

          猜你喜欢
          • 2020-11-07
          • 2015-11-03
          • 2015-08-06
          • 2013-08-12
          • 2013-06-24
          • 1970-01-01
          • 2018-11-20
          • 1970-01-01
          相关资源
          最近更新 更多