다중 프로세스 교체와 결합

다중 프로세스 교체와 결합

다음과 같은 것을 시도했다고 가정해 보겠습니다.

$ paste ../data/file-{A,B,C}.dat

그리고 붙여넣기 전에 각 파일을 정렬하고 싶다는 점을 인식하세요(숫자 정렬 가정). 그런 다음 프로세스 대체를 사용하여 다음과 같이 작성해야 합니다.

$ paste <(sort -n ../data/file-A.dat) \
        <(sort -n ../data/file-B.dat) \
        <(sort -n ../data/file-C.dat)

여기서는 많은 반복을 볼 수 있는데 이는 좋지 않습니다. 각 프로세스 대체는 서로 격리되어 있으므로 여러 프로세스 대체에 걸쳐 있는 중괄호 확장이나 경로 이름 확장(와일드카드 문자)을 사용할 수 없습니다.

sort -n이를 간결한 방식으로 작성하고(예: 및 별도로 제공 ../data/file-{A,B,C}.dat) 전체 명령줄을 작성할 수 있는 도구가 있습니까 ?

답변1

다음을 수행할 수 있습니다.

eval paste '<(sort -n ../data/file-'{A,B,C}'.dat)'

아니면 함수로 자동화하세요

sort_paste() {
  local n i cmd
  n=1 cmd=paste
  for i do
    cmd="$cmd <(sort -n -- \"\${$n}\")"
    n=$(($n + 1))
  done
  eval "$cmd"
}
sort_paste  ../data/file-{A,B,C}.dat

(일부 구현에서는 로 ksh바꿔야 함 )localtypeset

임의의 명령을 수용하고 eval올바르게 사용하면 안전하다는 것을 증명하려면 다음을 수행하십시오.

xproc() {
  local n i cmd stage stage1 stage2 stage3
  cmd= xcmd= stage=1 n=1
  stage1='cmd="$cmd \"\${$n}\""'
  stage2='xcmd="$xcmd \"\${$n}\""'
  stage3='cmd="$cmd <($xcmd \"\${$n}\")"'
  for i do
    if [ -z "$i" ] && [ "$stage" -le 3 ]; then
      stage=$(($stage + 1))
    else
      eval 'eval "$stage'"$stage\""
    fi
    n=$(($n + 1))
  done
  eval "$cmd"
}

xproc paste '' sort -n -- '' ../data/file-{A,B,C}/dat

답변2

보다여기, eval사용하는 것이 위험할 수 있는 이유. 아시다시피 이것은매우 강력한 도구, 하지만 동시에큰 피해를 초래하다.

다음 스크립트는 원하는 작업을 안전하게 수행합니다.

sort_ps () 
{ 
    local cmd="$1" p=()
    shift;
    for f in "$@"; do
        p+=(<(sort -n "$f"));
    done
    "$cmd" "${p[@]}"
}

편집자: Chazeras 씨가 옳습니다. sort_ps paste file1.txt file2.txt file2.txt ... fileN.txt지금 사용할 수 있도록 솔루션을 수정했습니다 . 내 답변을 검토해 주신 Stephen에게 감사드립니다.

예제 출력:

rany$ sort_ps sprunge foo1.txt foo.txt 
http://sprunge.us/EBZf?/dev/fd/62
http://sprunge.us/TQGC?/dev/fd/62

관련 정보