파일을 인라인으로 수정하고 stdin/stdout을 허용하도록 하는 명령을 실행합니다.

파일을 인라인으로 수정하고 stdin/stdout을 허용하도록 하는 명령을 실행합니다.

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사용하여 이 문제를 다소 완화 할 수 있습니다.--tmpdirmktemp

&&요즘에는 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중요하다면 적절하게 처리하세요.

traprm문제가 발생하더라도 방탄 기능을 강화하도록 설정하여 이를 수행할 수 있는 옵션이 있습니다 .

답변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

관련 정보