여러 명령을 더 적은 명령으로 파이프

여러 명령을 더 적은 명령으로 파이프

어떡해

{$several_commands} | less

less이를 여러 파일로 처리하고 탐색을 사용 하고 :n활성화합니다 :p.

이는 더 명확한 설명이 아닐 수 있으므로 예를 들어 보겠습니다. 현재 기능이 있습니다

svndiff () 
{ 
    for a in `svn status | \grep ^M | sed 's/M       //'`;
    do
        svn diff $a | less;
    done
}

목적은 분명히 less내가 수정한 모든 파일의 차이점을 확인하는 것입니다. 하지만 이 구문을 사용하면 Q하나의 "파일"을 닫고 다음 "파일"을 열려면 키를 사용해야 합니다 . (다음 파일) 및 (이전 파일) less명령을 사용하여 파일 간을 탐색할 수 있기를 원합니다 . 어떻게 해야 하나요?:n:p

답변1

프로세스 대체를 사용할 수 있습니다.

less -f <(svn diff this) <(svn diff that)

그러나 이것은 루프에서 사용하기가 어렵습니다. 아마도 임시 파일을 사용하는 것이 더 나을 것입니다.

#!/bin/bash
dir=$(mktemp -d)
outfiles=()
IFS=$'\n'
set -f 
for file in $(svn status | \grep ^M | sed 's/M       //') ; do
    outfile=${file#.}             # remove leading dot (if any)
    outfile=${outfile//\//__}     # replace slashes (if any) with __
    svn diff "$file" > "$dir/$outfile";
    outfiles+=("$dir/$outfile")   # collect the filenames to an array
done
less "${outfiles[@]}"
rm -r "$dir"

위의 코드는 임시 파일 이름에 파일 이름이 표시되도록 유지하고 슬래시와 선행 점을 일부 정리합니다. (이런 경로를 얻으면 . 파일명을 ./foo/bar어떻게 출력하는지 기억은 안나지만 뭐...)svn

@Kusalananda가 말했듯 "$dir"/*이 순서가 중요하지 않다면 그렇게 할 수 있지만 배열은 순서를 유지하기 위해 존재합니다. 누군가가 전역 문자나 공백을 사용하여 파일 이름을 만드는 set -f경우 .IFS=$'\n'

물론 스크립트를 약간 단순화하고 번호가 매겨진 임시 파일을 만들 수도 있습니다.

답변2

:n이동 하고 싶고 :p명령을 실행하는 것 외에 다른 방법이 없다면 출력을 파일로 출력한 후 다음을 수행하십시오 less.

svndiff () 
{
    d=$(mktemp -d /tmp/svndiffsXXXXX)
    for a in $(svn status | \grep ^M | sed 's/M       //');
    do
        svn diff "$a" > $(mktemp $d/diffXXXXX) 2>&1;
    done
    less "$d"/diff*
    rm -fr "$d"
}

(필요하신 분은 알려주시면 번호를 적용해드리겠습니다.)

그렇지 않으면 모든 명령을 실행하는 셸을 호출한 다음 연결된 출력을 less.

답변3

GNU Parallel을 사용하면 비슷한 작업을 수행할 수 있습니다.

files=$(svn status | \grep ^M | sed 's/M       //' |
  parallel --files svn diff {})
less $files
rm $files

관련 정보