我是Unix shell脚本的新手,并试图获得shell脚本的一些知识。请检查我的要求和我的方法。
我有一个包含数据的输入文件
ABC = A:3 E:3 PS:6
PQR = B:5 S:5 AS:2 N:2
我正在尝试解析数据并将结果作为
ABC
A=3
E=3
PS=6
PQR
B=5
S=5
AS=2
N=2
可以水平和垂直添加值,因此我尝试使用数组。我正在尝试这样的事情:
myarr=(main.conf | awk -F"=" 'NR!=1 {print $1}'))
echo ${myarr[1]}
# Or loop through every element in the array
for i in "${myarr[@]}"
do
:
echo $i
done
或
awk -F"=" 'NR!=1 {
print $1"\n"
STR=$2
IFS=':' read -r -a array <<< "$STR"
for i in "${!array[@]}"
do
echo "$i=>${array[i]}"
done
}' main.conf
但是当我将此代码添加到.sh
文件并尝试运行它时,我会收到语法错误
$ awk -F"=" 'NR!=1 {
> print $1"\n"
> STR=$2
> FS= read -r -a array <<< "$STR"
> for i in "${!array[@]}"
> do
> echo "$i=>${array[i]}"
> done
>
> }' main.conf
awk: cmd. line:4: FS= read -r -a array <<< "$STR"
awk: cmd. line:4: ^ syntax error
awk: cmd. line:5: for i in "${!array[@]}"
awk: cmd. line:5: ^ syntax error
awk: cmd. line:8: done
awk: cmd. line:8: ^ syntax error
我如何完成上述期望?
答案 0 :(得分:5)
这是执行您想要的awk代码:
ipengine --profile=/path/to/ipcontroller-engine.json
这是shell脚本(是的,所有shell脚本操作文本都是调用awk):
$ cat tst.awk
BEGIN { FS="[ =:]+"; OFS="=" }
{
print $1
for (i=2;i<NF;i+=2) {
print $i, $(i+1)
}
print ""
}
UNIX shell是一个可以从中调用UNIX工具的环境(查找,排序,sed,grep,awk,tr,cut等)。它有自己的语言来操作(例如创建/销毁)文件和进程以及对工具的调用排序,但它并不打算用于操作文本。发明shell的人也发明了awk for shell来调用操作文本。
阅读https://unix.stackexchange.com/questions/169716/why-is-using-a-shell-loop-to-process-text-considered-bad-practice和Arnold Robbins撰写的Effective Awk Programming,4th Edition一书。
答案 1 :(得分:2)
首先,执行你想要的命令:
$ sed 's/ = /\n/;y/: /=\n/' main.conf
ABC
A=3
E=3
PS=6
PQR
B=5
S=5
AS=2
N=2
这将在每一行上替换 =
第一次(仅出现)的换行符(s
命令),然后将所有:
转换为=
和所有空格分为换行符(y
命令)。注意
至于你所尝试的内容,尝试逐个修复它几乎有太多错误:从awk和Bash的狂野混合到整个地方的语法错误。我建议你阅读两篇很好的教程,例如:
这是一种在Bash中解决同样问题的方法;我没有使用任何阵列。
#!/bin/bash
# Read line by line into the 'line' variable. Setting 'IFS' to the empty string
# preserves leading and trailing whitespace; '-r' prevents interpretation of
# backslash escapes
while IFS= read -r line; do
# Three parameter expansions:
# Replace ' = ' by newline (escape backslash)
line="${line/ = /\\n}"
# Replace ':' by '='
line="${line//:/=}"
# Replace spaces by newlines (escape backslash)
line="${line// /\\n}"
# Print the modified input line; '%b' expands backslash escapes
printf "%b" "$line"
done < "$1"
输出:
$ ./SO.sh main.conf
ABC
A=3
E=3
PS=6
PQR
B=5
S=5
AS=2
N=2