如何迭代逗号分隔的列表并为每个条目执行命令

如何迭代逗号分隔的列表并为每个条目执行命令

我得到了一个命令,该命令输出变量中 autosys 作业的逗号分隔列表$all_jobs

box=box-of-jobs;all_jobs=$(jobscout -box $box | egrep "^\w+" | tr '\n' ','  | sed s/.$//); 

我想为列表中的每个项目调用 sendevent 命令:

sendevent -verbose -S NYT -E JOB_OFF_HOLD -J $job --owner me

例如,如果$all_jobs评估 job1,job2,job3

我想打电话

sendevent -verbose -S NYT -E JOB_OFF_HOLD -J job3 --owner me
sendevent -verbose -S NYT -E JOB_OFF_HOLD -J job2 --owner me
sendevent -verbose -S NYT -E JOB_OFF_HOLD -J job1 --owner me

我确信我可以编写一个 ksh 脚本来循环,但我知道使用 awk/sed 通常可以更快地编写这些东西,这两者我都不是很熟悉,所以它超出了我的技能范围。我正在使用 ksh(而不是 bsh)。

答案1

shell 中内置了在特定字符处拆分字符串的非常深的功能:如果您编写时$var没有任何周围的引号,那么它会按如下方式扩展:

  1. 取变量的值var
  2. 将此值拆分为字段列表。字段分隔符是变量值中的任意字符IFS。如果IFS包含空格字符,则连续的分隔符被视为一个;对于非空白字符,连续的分隔符会导致空字段。
  3. 执行通配符,即将每个结果字段解释为文件名通配符模式。对于与一个或多个文件匹配的每个模式,将其替换为匹配文件列表。

命令替换也会发生同样的情况$(somecommand),只不过步骤 1 是“收集运行的输出somecommand并在末尾删除所有换行符”。

为了避免所有这些繁琐的内容并仅获取变量的确切值或命令的输出减去最后的换行符,请务必将变量替换或命令替换放在双引号之间:"$foo", "$(foo)"

要以逗号字符分割命令替换的结果,请设置IFS=,替换并将其保留为不受保护。您还需要做一件事:关闭通配符,使用set -f(并随后使用 恢复它)set +f

all_jobs=$(…)
set -f; IFS=,
for job in $all_jobs; do
  sendevent -verbose -S NYT -E JOB_OFF_HOLD -J "$job" --owner me
done
set =f; unset IFS

答案2

如果您确定逗号之间的字段不包含任何空格,那么您可以执行以下操作:

for job in $(echo $all_jobs | tr "," " "); do
    sendevent -verbose -S NYT -E JOB_OFF_HOLD -J "$job" --owner me
done

如果您需要更强大的东西,请看看Unix下处理CSV文件所需的工具

答案3

您可以使用xargs

all_jobs="job1,job2,job3"
echo $all_jobs | tr '\n' ' ' | xargs -d, --replace=xx sendevent -verbose -S NYT -E JOB_OFF_HOLD -J xx --owner me

如果末尾没有换行符,则tr可能不需要管道通过$all_jobs

相关内容