다음과 같은 것을 시도했다고 가정해 보겠습니다.
$ 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
바꿔야 함 )local
typeset
임의의 명령을 수용하고 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