arrays - 精炼 Bash 循环
问题描述
你好 Stackoverflow 社区,
请原谅我的天真,但我有一个基本的循环脚本运行一个更复杂的脚本,该脚本正在寻找一个文本文件以获取我作为数组的输入。我猜我让它工作了,但我知道这可以运行得更好、更自动化。
这是我的脚本查找的文本文件;
2014;14204;
2015;15042;
2015;15062;
...
end;
这是我作为循环运行的 bash 脚本;
{ while IFS=';' read YEAR1 PROJ1 YEAR2 PROJ2 YEAR3 PROJ3 fake
do
{ echo "$YEAR1" | egrep '^#|^ *$' ; } > /dev/null && continue
$local/script.sh \
--forinput1 $YEAR1/$PROJ1 \
--forinput2 $YEAR2/$PROJ2 \
--forinput3 $YEAR3/$PROJ3 \
done
} < textFile.txt
我自己做了一些研究,发现了一些我认为可行但无法正确实施的方法。如果您能给我一些建议,我将不胜感激。
编辑:我很抱歉,所以脚本确实可以识别文本文件:
YEAR1;PROJ1;
YEAR2;PROJ2;
YEAR3;PROJ3;
使用 ”;” 作为其分隔符。它确实在循环中运行,直到它完成的最后一个变量。但是,对于它的功能,我需要在文本文件中添加额外的行
YEAR4;PROJ4;
YEAR5;PROJ5;
end;
然后添加脚本
{ while IFS=';' read YEAR1 PROJ1 YEAR2 PROJ2 YEAR3 PROJ3 YEAR4 PROJ4 YEAR5 PROJ5 fake
do
{ echo "$YEAR1" | egrep '^#|^ *$' ; } > /dev/null && continue
$local/script.sh \
--forinput1 $YEAR1/$PROJ1 \
--forinput2 $YEAR2/$PROJ2 \
--forinput3 $YEAR3/$PROJ3 \
--forinput4 $YEAR4/$PROJ4 \
--forinput5 $YEAR5/$PROJ5 \
done
} < textFile.txt
我希望完成的是在数组中添加变量,但不必在脚本中添加额外的语法
这是坏的,但我猜我在看什么
{ while IFS=';' read -a YEAR PROJ < textFile.txt
for ((i = 0; i < "${#YEAR[@]};${#PROJ[@]}"; i++)); do
{ echo "$YEAR[$i]" | egrep '^#|^ *$' ; } > /dev/null && continue
$local/script.sh \
--forinput[$i] ${YEAR[$i]}/${PROJ[$i]} \
done
}
解决方案
您的代码表明每个输入行有 6 个字段,这可能会导致代码如下
sed -nr 's#([^;]*);([^;]*);([^;]*);([^;]*);([^;]*);([^;]*);#$local/script.sh --forinput \1/\2 --forinput \3/\4 --forinput \5/\6#p' textFile.txt
# or shorter
f='([^;]*;)'
sed -nr 's#'$f$f$f$f$f$f'#$local/script.sh --forinput \1/\2 --forinput \3/\4 --forinput \5/\6#p' textFile.txt
当你必须结合 3 行输入时,你不应该尝试变得聪明。
# Don't do this
cat textFile.txt | paste -d'X' - - - | tr -d 'X'
# Trying to make
sed -nr 's#'$f$f$f$f$f$f'#$local/script.sh --forinput \1/\2 --forinput \3/\4 --forinput \5/\6#p' <(cat textFile.txt | paste -d'X' - - - | tr -d 'X')
在自豪地展示代码之后,您会发现当第二行是注释(以“#”开头)时,您将不得不使代码变得更糟。您需要替换cat textFile.txt
为grep -Ev '^#|^ *$' testFile.txt
.
当您需要关联不同的行时,请查看awk
.
没有检查的解决方案是
awk -F';' '{line++}
{param=param " --forinput " $1 "/" $2}
line==3 {print "$local/script.sh" param ; param=""; line=0}
' textFile.txt
您可以添加所有类型的检查。
推荐阅读
- vim - 如何让 NERDTree 在导航时调整视图?
- javascript - 允许在相关日期将任务添加到清单的脚本
- python - Python 从 Arduino 读取串行并跳过第一行读取
- image - 我们可以在matlab中计算用于线分割的霍夫线变换的精度吗?
- java - 如何使用 Code Pipeline 持续部署到 CloudFormation 堆栈
- docker - 通过自动构建推送映像时,如何将 Dockerfile 上传到 Docker Hub?
- laravel - 如何在 laravel 中加入数据透视表
- java - WebSockets with actor vs Akka 直接流,我应该使用哪一个?
- javascript - Javascript:无法打印由 Object.defineProperty 定义的对象属性
- windows - Visual Studio 2017 Community 15.9.5 需要较新版本的 Windows 才能显示内容,但较新的窗口被禁止