将命令中的列分离成新命令

将命令中的列分离成新命令

我正在尝试创建一个用于自动创建设备的脚本。我已经走了很远了,但我陷入了困境。

源文件如下所示:

dev1 size 1024
dev2 size 1024
dev3 size 1024
dev4 size 512
dev5 size 512

在脚本中,源文件是变量 $INVFILE。然后我发出命令

cat $INVFILE | awk '{print $3}' | sort | uniq -c

给出以下输出:

   3 1024
   2 512

我想在以下命令中使用此输出,以便它使用不同的大小及其计数(在本示例中,我仅使用第一行,但在脚本中我想以“对于 i in" 函数)。

create dev count=3 size=1024MB

我怎样才能在脚本中做到这一点?有没有更简单的方法来代替“for i in”函数?

答案1

awk 可以完成所有工作。

尝试

awk '{ d[$3]++ ; } 
     END { for ( c in d ) 
        printf "create dev count=%d size=%dMB\n",d[c],c ;}' $INVFILE

如果它有效:

awk '{ d[$3]++ ; } 
   END { for ( c in d ) 
         printf "create dev count=%d size=%dMB\n",d[c],c ;}' $INVFILE |
bash

答案2

awk '{print $3}' $INVFILE | sort | uniq -c | \
while read a b ; do \
    create dev count=$a size=${b}MB ; \
done

为了每个循环周期仅使用一个列表项,当读取 x_1 x_2 x_3...无论使用多少x_ns有,(但绝不会超过输入文件一行中的项目数量)。

笔记,如果任何输入的列数超过两列,将上面的“read a b”更改为“read ab c”——$c不会在循环中使用,但它会阻止 read 将行的其余部分分配给$b


第一行管道可以替换为数据混合, 和$a&$b在循环中交换:

datamash -W -s -g3 count 3 < $INVFILE | \
while read a b ; do \
    create dev count=$b size=${a}MB ; \
done

答案3

首先,'uniq' - 命令有一个忽略 n 列的选项:'-f N'。

之后,您可以将输入中的字段放入带有“read”的变量中。

因此,总的来说,以下命令将从输入文件的所有行中选取所需的信息:

cat input.txt | uniq -f2 -c | while read a b c d; do echo "command $a $d" ;done

将“echo ...”替换为您的命令。

相关内容