我对 shell 脚本非常陌生,并且正在尽我最大的努力来掌握这种语言。我正在尝试将文本文件中可用的每一行分配给一个数组
我想将每一行分配给一个数组,如下所示。
预期输出:
Array[0]="delectus aut autem"
Array[1]="quis ut nam facilis et officia qui"
Array[2]="fugiat veniam minus"
但是,在执行下面的代码时,我们观察到数组中的每个元素都是根据每行中的空间分配的
Shell 脚本:
#!/bin/sh
cmd=$(curl https://jsonplaceholder.typicode.com/todos)
echo $cmd > Data.json
echo $(jq '.[] | .title' Data.json) > title.txt
echo "text file creation done!"
filename=title.txt
declare -a myArray
myArray=(`cat "$filename"`)
printf '%s\n' "${myArray[@]}"
for (( i = 0 ; i < 20 ; i++))
do
echo "Element [$i]: ${myArray[$i]}"
done
电流输出:
有人可以解释一下吗?
您最大的问题是使用 POSIX shell 解释器行
#!/bin/sh
。 POSIX shell 不支持数组。您需要使用像 bash
这样的高级 shell,它提供 indexed、declare -a
数组和 associative、declare -A
数组。鉴于您使用 declare -a
,看来您打算使用 bash
。
您更幸运,
bash
提供了mapfile
(与readarray
同义)内置命令,可以将文件逐行读取到索引数组的元素中。您可以使用 mapfile
或 readarray
,它们是相同的命令,只是彼此的别名。
然后,当您想要循环数组时,请使用参数扩展
${#myArray[@]}
返回数组中的元素数量,而不是硬编码 20
或其他数字。
不必要时不要使用
cat ...
来传递信息。这称为 UUOc(不必要使用 cat
,也称为 无用使用 cat
)。请参阅猫的无用使用。而是使用 >
和 <
重定向到文件/从文件重定向。
始终将脚本粘贴到 ShellCheck 中以查找任何问题(在此处发布之前也是个好主意)
总而言之,您可以按如下方式修改脚本。这不是唯一的方法,但却是一种合理的方法:
#!/bin/bash
## assign filenames from 1st two command-line arguments
# use Data.json and title.txt by default if no arguments given
websrc="${1:-Data.json}"
txtfile="${2:-title.txt}"
## use redirection to save the curl data to Data.json
curl https://jsonplaceholder.typicode.com/todos > "$websrc"
## use redirection to save jq output to title.txt
jq '.[] | .title' "$websrc" > "$txtfile"
## optional output, but make information useful
# check "%txtfile" exists and is non-empty
if [ -s "$txtfile" ]; then
printf "text file creation done!\n"
else # otherwise handle the error and exit with error code 1
printf "error: failed to create txtfile '%s'\n" "$txtfile" >&2
exit 1
fi
## declare indexed array
declare -a myArray
## read the $txtfile into array
mapfile -t myArray < "$txtfile"
## no need to duplicate output
# printf '%s\n' "${myArray[@]}"
## use array to determine number of elements (200 in test)
for (( i = 0 ; i < ${#myArray[@]}; i++))
do
printf "Element [%d]: %s\n" "$i" "${myArray[$i]}"
done
示例使用/输出
由于您提供了 URL,因此脚本的输出为:
$ bash curl-json-mapfile.sh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 24311 0 24311 0 0 136k 0 --:--:-- --:--:-- --:--:-- 137k
text file creation done!
Element [0]: "delectus aut autem"
Element [1]: "quis ut nam facilis et officia qui"
Element [2]: "fugiat veniam minus"
Element [3]: "et porro tempora"
Element [4]: "laboriosam mollitia et enim quasi adipisci quia provident illum"
Element [5]: "qui ullam ratione quibusdam voluptatem quia omnis"
Element [6]: "illo expedita consequatur quia in"
Element [7]: "quo adipisci enim quam ut ab"
Element [8]: "molestiae perspiciatis ipsa"
Element [9]: "illo est ratione doloremque quia maiores aut"
Element [10]: "vero rerum temporibus dolor"
...
Element [195]: "consequuntur aut ut fugit similique"
Element [196]: "dignissimos quo nobis earum saepe"
Element [197]: "quis eius est sint explicabo"
Element [198]: "numquam repellendus a magnam"
Element [199]: "ipsam aperiam voluptates qui"
所有 200 个元素成功存储在数组中,并且比使用
read -r
循环要容易得多(这是另一个有效选项)
仔细检查一下,如果有疑问请告诉我。