Bash 拆分一个数组,添加一个变量并将其连接在一起



我一直在试图解决这个问题,不幸的是我不能。 我正在尝试创建一个函数,该函数可以找到";"字符,在它之前放置四个空格,然后将代码重新组合在一个整洁的句子中。 我已经破解了一段时间,但无法弄清楚一些事情。 我无法让输出显示我想要的内容。 我尝试查找";"字符的索引,但似乎我以错误的方式处理它。 我似乎犯的另一个错误是,我试图在 for 循环中拆分数组,然后按字母拆分数组中的各个单词,但我也不知道该怎么做。 如果有人能给我一个指针,这将不胜感激。这是在 bash 版本 4.3.48 中

#!commentPlacer() 
{
arg=($1)   #argument
len=${#arg[@]}    #length of the argument
comment=;    #character to look for in second loop
commaIndex=(${arg[@]#;})   #the attempted index look up
commentSpace="    ;"    #the variable being concatenated into the array
for(( count1=0; count1 <= ${#arg[@]}; count1++ ))  #search the argument looking for comment space
do  if [[  ${arg[count1]} != commentSpace ]]  #if no commentSpace variable then
then  for (( count2=0; count2 < ${#arg[count1]} ; count2++ ))    #loop through again
do if [[ ${arg[count2]} != comment  ]]  #if no comment
then A=(${arg[@]:0:commaIndex})
A+=(commentSpace)
A+=(${arg[@]commaIndex:-1})  #concatenate array
echo "$A"
fi
done
fi
done
}

如果我正确理解你想要什么,基本上就是在参数中的每个";"前面放 4 个空格,然后打印结果。这实际上很容易在带有字符串替换的 bash 中完成:

commentPlacer() {
echo "${1//;/    ;}"
}

这里的扩展格式为${variable//pattern/replacement},它给出了变量的内容,每次出现的pattern都替换为replacement。请注意,在模式之前只有一个/,它将仅替换第一个匹配项。

现在,我不确定我是否理解您的脚本应该如何工作,但我看到一些事情显然没有按照您的期望去做。以下是我看到的问题的快速摘要:

arg=($1)   #argument

这不会从第一个参数创建字符数组。var=(...)( )中的事物视为单词列表,而不是字符。由于$1不在双引号中,因此它将根据空格(通常是空格、制表符和换行符(拆分为单词,然后任何包含通配符的单词都将扩展为匹配文件名的列表。我很确定这根本不是你想要的(事实上,它几乎从来都不是你想要的,所以变量引用几乎总是应该用双引号来防止它(。在 bash 中创建字符数组并不容易,而且通常不是您想要做的事情。您可以使用${var:index:1}访问字符串变量中的各个字符,其中index是您想要的字符(从 0 开始计数(。

commaIndex=(${arg[@]#;})   #the attempted index look up

这不会执行查找。替换${var#pattern}给出var的值,pattern从前面删除(如果匹配(。如果有多个可能的匹配项,则使用最短的匹配项。变体${var##pattern}使用最长的匹配。使用${array[@]#pattern},它将尝试从每个元素中删除模式 - 并且由于它不在双引号中,因此其结果像往常一样被单词拆分和通配符扩展。我很确定这根本不是你想要的。

if [[  ${arg[count1]} != commentSpace ]]  #if no commentSpace variable then

在这里(以及许多其他地方(,你使用的是前面没有$的变量;这根本不使用变量,它只是将"commentSpace"视为静态字符串。此外,在一些地方,用双引号括起来很重要,例如,保持$commentSpace中的空格不会因单词拆分而消失。有些地方可以安全地关闭双引号,但总的来说,很难跟踪它们,所以只需在任何地方使用双引号。

一般建议:不要试图用bash编写C(或Java或其他(程序;它的工作方式太不同了,你必须以不同的方式思考。使用 shellcheck.net 发现常见问题(如非双引号变量引用(。最后,您可以通过将set -x放在未按预期执行的部分之前来查看 bash 在做什么;这将使 bash 在执行时打印每一行,显示它正在执行的等效内容。

在 stdin(标准(上使用模式替换创建一个小函数:

semicolon4s() { while read x; do echo "${x//;/    ;}"; done; }
semicolon4s <<< 'foo;bar;baz'

输出:

foo    ;bar    ;baz

相关内容

最新更新