쉼표로 구분된 목록을 반복하고 각 항목에 대해 명령을 실행하는 방법

쉼표로 구분된 목록을 반복하고 각 항목에 대해 명령을 실행하는 방법

변수에 쉼표로 구분된 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_jobsjob1,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를 사용하여 이러한 내용을 작성하는 것이 더 빠르다는 것을 알고 있습니다. 두 가지 모두 익숙하지 않으므로 내 기술 수준을 벗어납니다. 저는 bsh가 아닌 ksh를 사용하고 있습니다.

답변1

$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

관련 정보