다음과 같은 것을 시도했다고 가정해 보겠습니다.
$ 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[@]}"
}
편집: 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