여러 프로세스 대체 결합

여러 프로세스 대체 결합

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

$ 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[@]}"
}

편집: Chazelas 씨가 옳습니다. 내 솔루션을 수정했으므로 이제 sort_ps paste file1.txt file2.txt file2.txt ... fileN.txt대신 사용할 수 있습니다. 내 답변을 검토해 주신 Stephane에게 감사드립니다.

샘플 출력:

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

관련 정보