从 bash 中的文件行获取字符串
get string from lines of file in bash
我在文件中有这些行:
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
我需要分隔第二列值来处理 them.I 已完成此代码:
pid=$(cat idle_log.txt | cut -d" " -f2)
echo $pid
但它只给了我 28811 32200 32252 在 results.as 你看列表中没有 2609 2758 的踪迹,我也想得到它们。
我还想在提取 pids 后对它们进行计数。
我用过:
npid=$(grep -o " " <<< $pid | grep -c .)
它 returns 2 对于 28811 32200 32252 的结果我需要它 return 3 作为进程数。
最后我想逐行处理一些事情,就像在 while 循环中一样,但是命令的输出 return 一次结果,我不能以循环格式逐个处理它们。
谢谢大家的帮助。
$ 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 }' 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
您可以使用tr
压缩space然后使用cut
取第二个space分隔字段:
tr -s ' ' <idle_log.txt | cut -d' ' -f2
或awk
:
awk '{ print }' idle_log.txt
或sed
:
sed -r 's/^[^[:blank:]]+[[:blank:]]+([^[:blank:]]+)(.*)//' idle_log.txt
或grep
:
grep -Po '^[^\s]+\s+\K[^\s]+' idle_log.txt
为了use/count他们以后使用数组:
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 }' file.txt
2609
2758
28811
32200
32252
$ sed -r 's/^[^[:blank:]]+[[:blank:]]+([^[:blank:]]+)(.*)//' file.txt
2609
2758
28811
32200
32252
$ grep -Po '^[^\s]+\s+\K[^\s]+' file.txt
2609
2758
28811
32200
32252
cut
完全使用您传递给它的定界符。这意味着使用分隔符 ' '
,第一行是:
postgres, <empty>, 2609
最后一个是:
postgres, 32252
你可以通过 运行 简化这个 awk '{print }' idle_log.txt
使用 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
我会选择最简单的解决方案:
pid=$(awk '{print }' idle_log.txt)
echo $pid
sed 和 grep 的正则表达式在脚本中的可读性要差得多,而 cut 和 tr 有时可能会产生意想不到的结果。
正如已经指出的那样,您没有得到结果的原因是您没有提取第二列。
相反,您使用的是命令 cut -d" " -f2
,因此您得到了每行的第二个表空间分割。您可能会看到前两行有一个额外的表空间,因此您应该使用 cut -d" " -f3
但正如所讨论的,这不是获取第二列的正确方法。请改用 awk '{print }'
。
我在文件中有这些行:
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
我需要分隔第二列值来处理 them.I 已完成此代码:
pid=$(cat idle_log.txt | cut -d" " -f2)
echo $pid
但它只给了我 28811 32200 32252 在 results.as 你看列表中没有 2609 2758 的踪迹,我也想得到它们。 我还想在提取 pids 后对它们进行计数。 我用过:
npid=$(grep -o " " <<< $pid | grep -c .)
它 returns 2 对于 28811 32200 32252 的结果我需要它 return 3 作为进程数。 最后我想逐行处理一些事情,就像在 while 循环中一样,但是命令的输出 return 一次结果,我不能以循环格式逐个处理它们。
谢谢大家的帮助。
$ 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 }' 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
您可以使用tr
压缩space然后使用cut
取第二个space分隔字段:
tr -s ' ' <idle_log.txt | cut -d' ' -f2
或awk
:
awk '{ print }' idle_log.txt
或sed
:
sed -r 's/^[^[:blank:]]+[[:blank:]]+([^[:blank:]]+)(.*)//' idle_log.txt
或grep
:
grep -Po '^[^\s]+\s+\K[^\s]+' idle_log.txt
为了use/count他们以后使用数组:
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 }' file.txt
2609
2758
28811
32200
32252
$ sed -r 's/^[^[:blank:]]+[[:blank:]]+([^[:blank:]]+)(.*)//' file.txt
2609
2758
28811
32200
32252
$ grep -Po '^[^\s]+\s+\K[^\s]+' file.txt
2609
2758
28811
32200
32252
cut
完全使用您传递给它的定界符。这意味着使用分隔符 ' '
,第一行是:
postgres, <empty>, 2609
最后一个是:
postgres, 32252
你可以通过 运行 简化这个 awk '{print }' idle_log.txt
使用 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
我会选择最简单的解决方案:
pid=$(awk '{print }' idle_log.txt)
echo $pid
sed 和 grep 的正则表达式在脚本中的可读性要差得多,而 cut 和 tr 有时可能会产生意想不到的结果。
正如已经指出的那样,您没有得到结果的原因是您没有提取第二列。
相反,您使用的是命令 cut -d" " -f2
,因此您得到了每行的第二个表空间分割。您可能会看到前两行有一个额外的表空间,因此您应该使用 cut -d" " -f3
但正如所讨论的,这不是获取第二列的正确方法。请改用 awk '{print }'
。