Bash脚本,命令 - 输出到数组,然后打印到文件

时间:2015-04-22 17:08:03

标签: bash shell

我需要有关如何实现此输出的建议:

myoutputfile.txt
    Tom Hagen 1892
    State: Canada
    Hank Moody 1555
    State: Cuba
    J.Lo 156
    State: France

mycommand的输出:

/usr/bin/mycommand
        Tom Hagen
        1892
        Canada
        Hank Moody
        1555
        Cuba
        J.Lo
        156
        France

我试图用这个shell脚本实现:

IFS=$'\r\n' GLOBIGNORE='*' :; names=( $(/usr/bin/mycommand) )
for name in ${names[@]}
do
#echo $name
echo ${name[0]} 
#echo ${name:0} 
done

由于

4 个答案:

答案 0 :(得分:3)

假设您始终可以依赖命令输出3行组,则一个选项可能是

/usr/bin/mycommand | 
  while read name;
        read year;
        read state; do
    echo "$name $year"
    echo "State: $state"
  done

这里不需要数组。

如果你不能获得所有三条必需的行,那么一个改进就是退出循环:

while read name && read year && read state; do
    # Guaranteed that name, year, and state are all set
    ...
done

答案 1 :(得分:2)

简单的单行程序(未针对性能进行调整):

/usr/bin/mycommand | xargs -d '\n' -L3 printf "%s %s\nState: %s\n"

它从管道一次读取3行,然后将它们传递给printf的新实例,用于格式化输出。

如果你在开头有空格(在你的示例输出中看起来像那样),你可能需要使用这样的东西:

/usr/bin/mycommand | sed -e 's/^\s*//g' | xargs -d '\n' -L3 printf "%s %s\nState: %s\n"

答案 2 :(得分:1)

SELECT AVG(CdPrice) as Price, Genre
FROM CD
GROUP BY Genre
HAVING AVG(CdPrice) = (
  SELECT MAX(Price) FROM (SELECT AVG(CdPrice) as Price FROM CD GROUP BY Genre) A
)

答案 3 :(得分:1)

  • chepner's pure bash solution简单而优雅,但输入文件较大(bash中的循环很慢)。
  • Michael Jaros' solution更简单,如果你有 GNU xargs(与xargs --version验证),但也不执行以及大输入文件(每3个输入行调用一次外部实用程序printf)。

如果效果重要,请尝试以下 awk解决方案

/usr/bin/mycommand | awk '
 { ORS = (NR % 3 == 1 ? " " : "\n")
  gsub("^[[:blank:]]+|[[:blank:]]*\r?$", "") } 
 { print (NR % 3 == 0 ? "State: " : "") $0 }
' > myoutputfile.txt
  • NR % 3返回其各自连续3行组中每个输入行的从0开始的索引;第1行返回1,第2行返回2,第3行返回0(!)。
  • { ORS = (NR % 3 == 1 ? " " : "\n")根据该索引确定输出记录分隔符ORS:第1行的空格,第2行和第3行的换行符;空格确保在使用print时,第2行会在第1行附加空格。
  • gsub("^[[:blank:]]+|[[:blank:]]*\r?$", "")从行中删除前导和尾随空格 - 包括(如果存在)尾随\r,您的输入似乎有。
  • { print (NR % 3 == 0 ? "State: " : "") $0 }打印修剪后的输入行,前缀为"状态:"仅适用于每个 3rd 输入行,并隐式后跟ORS(由于使用了print)。