我正在编写一个 bash 脚本,以“集中”并简化信息查找,供经验不足的员工在提供技术支持时使用。
从最严格的 Bash 脚本编写者的角度来看,这段代码的可接受程度如何?简而言之,这本质上是整个脚本(实际上是一个 bash shell,哈哈。)
#!/bin/bash
declare -a array
array=(`grep -w foo /var/log/bar.log | awk '{print $1,$2,$3,$14,$16}' | sed 's/<//g; s/>,//g; s/>//g;' | tr [:blank:] , && ssh XXX.XXX.XXX.XXX 'grep -w foo /var/log/bar.log' | awk '{print $1,$2,$3,$14,$16}' | sed 's/<//g; s/>,//g; s/>//g;' | tr [:blank:] ,`)
然后该脚本继续对阵列进行操作。我这样运行它的原因是因为我希望所有内容都保留在 RAM 中,如有必要我可以详细说明。
我知道代码非常丑陋,但是有没有更干净的方法可以在不改变我的目标、编程语言或添加额外代码行的情况下完成此操作?我知道我可以清理 sed regexp 但除此之外我目前想不出更好的东西......
答案1
是的,可能,有时……这要看情况。
很抱歉这个漫无目的的答案。问题没有提到数组的目的和用途,也没有提到数据文件的内容,所以很难说具体的事情。
摘要: 不,这不是在 shell 脚本中处理数据的常用/惯用方法。
编写的代码很难理解,因为它是相当长的一行。看起来大多数操作都可以由单个awk
脚本执行(今天我不会写这个脚本)。恐怕我的代码审查会失败。
您希望将(可能)大量数据放入数组中这一事实告诉我,您稍后将在一个或多个 shell 循环中处理该数组。如果只是一个循环,那么为什么不将结果直接传递到循环中呢?
我们拭目以待 ”为什么使用 shell 循环处理文本被认为是不好的做法?”。
如果命令管道仅以受限形式生成很少的项目(单个单词或字符串,否则保证在 shell 中表现良好),这可能仍然完全没问题,但这仍然不是惯用的做法。
数据必须在某个时刻被读取,您不妨在读取时使用它,而无需将其存储在数组中带来额外的麻烦。根据您对数据执行的操作,这可以通过awk
或sed
(或其他一些工具)直接完成。
据我所知,您正在生成逗号分隔的字符串,也许它会创建一个 CSV 数据集,其中每一行作为数组中的一个条目?这是完美的例如,再次输入awk
,而不将其临时存储在数组中。或者,进入其中之一CSV套件与此相关的工具。您甚至可以将其传递到真实文件并在一个或多个其他脚本中处理它。
对于处理大型数据集的人(像我一样)来说,将文件读入 shell 变量是不可能的。幸运的是,大多数标准 Unix 工具的作用类似于过滤器,并且可以使用管道或多或少地逐行在程序的各个阶段之间传递数据。将数据“读入 RAM”并不会加快速度。
我差一点就绝不将文件中的数据读取到任何类型的 shell 变量中。我更经常使用变量表示静态字符串、短期临时值或计数器,使用数组表示静态数据,因为当在数组上执行简单的参数替换比发送数组更容易时sed
(例如${arr[@]%.*}
剥离一些扩展名) )中的文件名arr
,或用于在短循环中聚合数据。