다음과 같이 실행되는 일련의 명령이 있습니다.
cmd1 < input > foo
cmd2 < foo > bar
cmd3 foo bar > output
중간 파일 없이 foo
이를 수행할 수 있는 방법이 있습니까 bar
?
또한 이 작업을 두 번 실행하는 것을 피하고 싶습니다 cmd1
.
cmd3 <(cmd1 < input) <(cmd1 < input | cmd2) > output
3가지 명령을 모두 실행하는 데 몇 시간이 걸릴 수 있으며 파일 크기는 1GB~100GB(생물정보학)입니다.
다음은 인위적이지만 실행 가능한 예입니다.
function cmd1 { sed -r 's/[246]/x/g'; }
function cmd2 { sed -r 's/[135]/-/g'; }
function cmd3 { paste $1 $2; }
seq 10 > input
cmd3 <(cmd1 < input) <(cmd1 < input | cmd2) # cmd1 runs twice
산출
1 -
x x
3 -
x x
5 -
x x
7 7
8 8
9 9
10 -0
이것이 도움이 될지는 확실하지 않지만 데이터가 다음과 같이 흐르기를 원합니다.
input --> cmd1 ---> cmd2 -->|
| |--> cmd3 --> output
------------>|
https://unix.stackexchange.com/a/43536가깝지만 충분하지는 않습니다.
답변1
이런 일이 가능합니까?
rm -f fifo
mkfifo fifo
cmd1 <input | tee fifo | cmd2 | cmd3 fifo /dev/stdin >output
그러면 이름이 지정된 파이프가 생성됩니다 fifo
. 첫 번째 명령은 명명된 파이프에 쓰기를 사용하고 두 번째 명령은 표준 입력을 사용합니다 tee
. 세 번째 명령은 명명된 파이프와 표준 입력에서 읽습니다.
디스크에는 중간 데이터가 저장되지 않지만 cmd3
파이프 버퍼가 가득 찰 때까지 명명된 파이프에서 소비가 이루어지지 않거나 cmd2
소비하는 데이터 양에 비해 생성되는 데이터가 매우 적은 경우 파이프가 교착 상태에 빠질 수 있습니다(및 , 대부분 중요한 것은 cmd3
파이프 버퍼가 가득 찰 때까지 충분한 소비를 생성하지 않는다는 것입니다 . fifo
당신은 할 수가능한작성자 사이트 (또는 그 변형) 에서 pv
사용되는 명명된 파이프의 데이터 버퍼링과 같은 방법을 사용하여 이 문제를 해결하십시오.cmd3 <( pv --quiet <fifo ) /dev/stdin
tee >( pv --quiet >fifo )