我正在尝试构造一个数组并以这种格式写入文件,即文件的内容应该是这样的
hero_pairscore=( askdjfh sdf,sdlkfj lksf,dfgdf,dsflkgj,asdlkf ....)
Run Code Online (Sandbox Code Playgroud)
其中元素由comma
. 我为此编写了以下代码。
#!/bin/bash
#set -x
hero_pairscore=()
while read line
do
$( IFS=",";hero_pairscore+=( "$line" )
done < true_pairscore.txt
echo "hero_pairscore=( ${hero_pairscore[@]} )" > embed.txt
Run Code Online (Sandbox Code Playgroud)
但是生成的文件只包含这个hero_pairscore=( )
. 我的代码有什么问题,如何更正它以提供所需的输出?
您需要做的就是:
设置变量。我们将使用这个:
var="kijhg, fbjhku,,,ioy fbjfr, kjmyhg"
Run Code Online (Sandbox Code Playgroud)设置$IFS
并防止文件名扩展:
IFS=, ; set -f
Run Code Online (Sandbox Code Playgroud)set
$@
要输出的shell数组。
set -- $var
Run Code Online (Sandbox Code Playgroud)重置父 shell$IFS
和 shell 参数:
unset IFS ; set +f
Run Code Online (Sandbox Code Playgroud)万岁!它甚至保留了多次重复和空格等等!
printf %s\\n "$@"
Run Code Online (Sandbox Code Playgroud)
输出
kijhg
fbjhku
ioy fbjfr
kjmyhg
Run Code Online (Sandbox Code Playgroud)无论如何,请相信我的话。每个不是 a 的字符都会,
被保留。
我特别推荐使用真正的 shell 数组而不是 bash 数组,因为您可以立即转换其拆分器。
printf %s "$*"
#OUTPUT#
kijhg fbjhku ioy fbjfr kjmyhg %
IFS=, ; printf %s "$*"
#OUTPUT#
kijhg, fbjhku,,,ioy fbjfr, kjmyhg
Run Code Online (Sandbox Code Playgroud)
因为$*
具有在第一个字符上拆分 shell 的位置参数参数数组的特殊 POSIX 指定质量,所以$IFS
您可以轻松地像这样简单地转换数据。您可以"quote"
-protect 参数数组并仍然将其拆分为您喜欢的任何单个字符。只要你第一次就做对了,那就是。
POSIX 还为"$@"
. 除了"$1"... eval "\${$#}"
每个参数的寻址形式之外,"$@"
参数 - 当引用时 - 安全地扩展到所有 shell 的参数,因为它们是最后一个,set
而不管当前的值是什么$IFS.
所以如果你想在数组的开头添加一个列表,你可以这样做:
set -- $list "$@"
Run Code Online (Sandbox Code Playgroud)
到头/尾:
set -- $head "$@" $tail
Run Code Online (Sandbox Code Playgroud)
将您的阵列增加三倍:
set -- "$@" "$@" "$@"
Run Code Online (Sandbox Code Playgroud)
除非您的数据流非常大,否则以下操作可能会比您当前的操作快一点(不过,如果您正在处理文件,最好完全避免 shell 拆分):
( set -f -- ; IFS=, ; while read -r line ; do set -- "$@" $line ; done
printf %s "$*" ) | cat >out
Run Code Online (Sandbox Code Playgroud)
我不明白的是——你在做什么?你想用逗号替换换行符吗?我的意思是 -除了换行符之外,数据是否已经用逗号分隔?如果是这样的话:
tr '\n' ',' <in >out
Run Code Online (Sandbox Code Playgroud)
做我认为你正在尝试做的事情,即将每个逗号分隔的字段读true_pairscore.txt
入一个数组变量,你的代码没有太大问题。将$(
在开始IFS
行显然是错误的,并会导致脚本有一个错误(也许这是你没有输出的原因)。除此之外,您的代码的主要修复只是删除周围的引号,$line
因为您想要bash
进行单词拆分IFS
(通常这是您使用它们来避免的):
#!/bin/bash
set -o noglob
OIFS=$IFS
IFS=","
hero_pairscore=()
while IFS= read -r line
do
hero_pairscore+=( $line )
done < true_pairscore.txt
echo "hero_pairscore=( ${hero_pairscore[@]} )" > embed.txt
set +o noglob
IFS=$OIFS
Run Code Online (Sandbox Code Playgroud)
但是,这里有一个技巧,只需两行即可完成上述操作:
IFS=$',\n' read -ra hero_pairscore -d '' <true_pairscore.txt
echo "hero_pairscore=( ${hero_pairscore[@]} )" > embed.txt
Run Code Online (Sandbox Code Playgroud)
如果embed.txt
要在另一个bash
shell 中获取文件,您可能希望引用写入hero_pairscore
数组的每个元素。为此,请将 替换为echo "hero_pairscore=( ${hero_pairscore[@]} )"
:
echo "hero_pairscore=( $(printf '"%s" ' "${hero_pairscore[@]}") )"
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5647 次 |
最近记录: |