파이프를 통해 셸의 여러 파일에 연결

파이프를 통해 셸의 여러 파일에 연결

나는 많은 양의 데이터를 생성하는 애플리케이션을 가지고 있는데, 그 애플리케이션이 디스크에 저장되는 것을 원하지 않습니다. 애플리케이션은 주로 사용하고 싶지 않은 데이터를 출력하지만, 별도의 파일로 분리해야 하는 유용한 정보 세트를 출력합니다. 예를 들어 다음과 같은 출력이 제공됩니다.

JUNK
JUNK
JUNK
JUNK
A 1
JUNK
B 5
C 1
JUNK

다음과 같이 애플리케이션을 세 번 실행할 수 있습니다.

./app | grep A > A.out
./app | grep B > B.out
./app | grep C > C.out

이렇게 하면 내가 원하는 것을 얻을 수 있지만 시간이 오래 걸릴 것입니다. 또한 모든 출력을 단일 파일로 덤프하고 구문 분석하고 싶지 않습니다.

위에 표시된 세 가지 작업을 결합하여 응용 프로그램을 한 번만 실행해도 세 개의 개별 출력 파일을 얻을 수 있는 방법이 있습니까?

답변1

당신이 가지고 있다면

./app | tee >(grep A > A.out) >(grep B > B.out) >(grep C > C.out) > /dev/null

(에서여기)

(프로세스 교체에 대해)

답변2

당신은 그것을 사용할 수 있습니다awk

./app | awk '/A/{ print > "A.out"}; /B/{ print > "B.out"}; /C/{ print > "C.out"}'

답변3

쉘을 사용할 수도 있습니다패턴 일치 기능:

./app | while read line; do 
     [[ "$line" =~ A ]] && echo $line >> A.out; 
     [[ "$line" =~ B ]] && echo $line >> B.out; 
     [[ "$line" =~ C ]] && echo $line >> C.out; 
 done

심지어:

./app | while read line; do for foo in A B C; do 
     [[ "$line" =~ "$foo" ]] && echo $line >> "$foo".out; 
  done; done

다음으로 시작하는 백슬래시와 줄을 처리하는 더 안전한 방법 -:

./app | while IFS= read -r line; do for foo in A B C; do 
     [[ "$line" =~ "$foo" ]] && printf -- "$line\n" >> "$foo".out; 
  done; done

@StephaneChazelas가 의견에서 지적했듯이 이는 그다지 효율적이지 않습니다. 가장 좋은 해결책은 다음과 같습니다.@AurélienOoms'.

답변4

다음은 Perl 언어 중 하나입니다:

./app | perl -ne 'BEGIN {open(FDA, ">A.out") and 
                         open(FDB, ">B.out") and 
                         open(FDC, ">C.out") or die("Cannot open files: $!\n")} 
                  print FDA $_ if /A/; print FDB $_ if /B/; print FDC $_ if /C/'

관련 정보