foo
파일을 가져와 해당 파일에서 몇 가지 변환(예: )을 수행하는 명령이 있다고 가정해 보겠습니다 sed -i
. 이 명령은 전통적인 "stdin에서 읽기, 변환, stdout에 쓰기" 옵션을 허용하지 않는 것으로 가정됩니다.
stdin/stdout 작업 흐름을 허용하도록 이 명령을 "변환"하는 방법이 있습니까?
내가 생각할 수 있는 첫 번째 일은 임시 파일을 사용하는 일종의 래퍼를 작성하는 것입니다. 하지만 이를 수행할 수 있는 표준화된 "메타 도구"(또는 일부 bash 트릭)가 있는지 궁금합니다.
답변1
약간 치즈 맛이 나지만 다음과 같습니다.
my_temp_file=$(mktemp)
cat > "$my_temp_file"
foo "$my_temp_file"
cat "$my_temp_file"
rm -f "$my_temp_file"
분명하지 않다면 이것은
- 표준 입력을 읽고 이를 파일에 씁니다.
foo
임시 파일에서 프로그램을 호출합니다.- 임시 파일을 읽고 표준 출력에 씁니다.
- 임시 파일을 삭제합니다.
작업 중인 데이터가 너무 커서 저장할 수 없는 경우 임시 파일을 더 많은 여유 공간이 있는 파일 시스템에 배치하는 옵션을 /tmp
사용하여 이 문제를 다소 완화 할 수 있습니다.--tmpdir
mktemp
&&
요즘에는 connect 명령이 매우 인기가 있습니다. 라고 말하는 것이 더 합리적일 수도 있습니다.
my_temp_file=$(mktemp) && {
cat > "$my_temp_file" && {
foo "$my_temp_file"
cat "$my_temp_file"
}
rm -f "$my_temp_file"
}
왜냐하면
- 실패 하면
mktemp
임시 파일도 없고 할 수 있는 일도 많지 않습니다. - 실패 하면
cat > "$my_temp_file"
입력을 캡처하지 않았으므로 할 수 있는 일이 없습니다(아직 임시 파일을 삭제하지 않는 한).
종료 상태가 foo
중요하다면 적절하게 처리하세요.
trap
rm
문제가 발생하더라도 방탄 기능을 강화하도록 설정하여 이를 수행할 수 있는 옵션이 있습니다 .
답변2
G-Man의 답변과 비슷하지만 함수로 포장되어 있습니다.
foo_stream() {
local t=$(mktemp) &&
cat - >| "$t" &&
foo "$t" &&
cat "$t" &&
rm "$t"
}
따라서 foo가 ( foo() { sed -i 's/.*/& & &/' "$1"; }
각 행의 "3배")인 경우 파이프라인에서 원하는 방식으로 foo_stream을 사용할 수 있습니다.
$ seq 10 | foo_stream | tac
10 10 10
9 9 9
8 8 8
7 7 7
6 6 6
5 5 5
4 4 4
3 3 3
2 2 2
1 1 1
set -o noclobber
참고: 실수로 기존 파일을 덮어쓰는 것을 방지하기 위해 이 방법을 사용합니다 . >|
리디렉션을 통해 덮어쓸 수 있습니다.
답변3
제어권이 있는 경우 foo
편집되지 않습니다.제자리에하지만 입력 파일을 제공할 수 있습니다.그리고결과물 파일:
foo() { sed 's/.*/& & &/' "$1" > "$2"; }
그런 다음 프로세스 대체를 사용하여 "입력 파이프" 및 "출력 파이프"를 나타낼 수 있습니다.
$ foo <(seq 10) >(tac)
10 10 10
9 9 9
8 8 8
7 7 7
6 6 6
5 5 5
4 4 4
3 3 3
2 2 2
1 1 1