bash를 사용하여 파일 (Argument)을 편집하는 명령을 어떻게 실행합니까?

StackOverflow https://stackoverflow.com/questions/146435

  •  02-07-2019
  •  | 
  •  

문제

나는 temp.txt 파일이 있습니다. sort bash에서 명령.

정렬 된 결과가 원본 파일을 대체하려고합니다.

예를 들어 작동하지 않습니다 (빈 파일이 나타납니다).

sortx temp.txt > temp.txt

임시 파일에 복사하지 않고 한 줄로 수행 할 수 있습니까?


편집 : -o 옵션은 매우 멋지다 sort. 나는 사용했다 sort 내 질문에서 예로. 다른 명령과 같은 문제가 발생합니다.

uniq temp.txt > temp.txt.

더 나은 일반 솔루션이 있습니까?

도움이 되었습니까?

해결책

sort temp.txt -o temp.txt

다른 팁

sort 출력을 시작하기 전에 모든 입력을 볼 필요가 있습니다. 이런 이유로 sort 프로그램은 파일을 내내 수정하는 옵션을 쉽게 제공 할 수 있습니다.

sort temp.txt -o temp.txt

구체적으로, GNU의 문서화 sort 말 :

일반적으로 Sort는 출력 파일을 열기 전에 모든 입력을 읽습니다. 따라서 명령을 사용하여 파일을 안전하게 정렬 할 수 있습니다. sort -o F F 그리고 cat F | sort -o F. 하지만, sort ~와 함께 --merge (-m) 모든 입력을 읽기 전에 출력 파일을 열 수 있으므로 cat F | sort -m -o F - G 정렬이 쓰기를 시작할 수 있으므로 안전하지 않습니다 F ~ 전에 cat 그것을 읽는 것입니다.

BSD의 문서 sort 말 :

the] output-file이 입력 파일 중 하나 인 경우 출력을 [출력 파일에 정렬하고 작성하기 전에 임시 파일에 복사하십시오.

다음과 같은 명령 uniq 입력 읽기를 마치기 전에 출력을 시작할 수 있습니다. 이 명령은 일반적으로 내장 편집을 지원하지 않습니다 (이 기능을 지원하기가 더 어려울 것입니다).

일반적으로 임시 파일 로이 문제를 해결하거나 중간 파일을 절대적으로하지 않으려면 버퍼를 사용하여 작성하기 전에 전체 결과를 저장할 수 있습니다. 예를 들어 perl:

uniq temp.txt | perl -e 'undef $/; $_ = <>; open(OUT,">temp.txt"); print OUT;'

여기에서 Perl Part는 완전한 출력을 읽습니다. uniq 변수 $_ 그런 다음이 데이터로 원본 파일을 덮어 씁니다. 선택한 스크립팅 언어, 아마도 Bash에서도 똑같이 할 수 있습니다. 그러나 전체 파일을 저장하기에 충분한 메모리가 필요합니다. 큰 파일로 작업 할 때는 권장되지 않습니다.

다음은보다 일반적인 접근 방식이 있습니다. Uniq와 함께 작동합니다.

{ rm file && uniq > file; } < file

스폰지에 대한 Tobu의 의견 그 자체로 답변이되는 것을 보증합니다.

인용 더 많은 사람들 홈페이지 :

아마도 지금까지 Moreutils에서 가장 일반적인 목적 도구는 스폰지 (1)이며, 이와 같은 일을 할 수 있습니다.

% sed "s/root/toor/" /etc/passwd | grep -v joey | sponge /etc/passwd

하지만, sponge 같은 문제로 고통받습니다 Steve Jessop은 여기에 댓글을 달았습니다. 이전에 파이프 라인의 명령 중 하나 인 경우 sponge 실패하면 원본 파일이 기록됩니다.

$ mistyped_command my-important-file | sponge my-important-file
mistyped-command: command not found

어 오, my-important-file 사라.

여기에 하나 줄 :

sort temp.txt > temp.txt.sort && mv temp.txt.sort temp.txt

기술적으로 임시 파일을 복사하지 않으며 'MV'명령은 즉각적이어야합니다.

나는 좋아한다 sort file -o file 답변이지만 같은 파일 이름을 두 번 입력하고 싶지 않습니다.

Bash 사용 역사 확장:

$ sort file -o !#^

누를 때 현재 라인의 첫 번째 arg를 잡습니다. 입력하다.

독특한 종류의 장소 :

$ sort -u -o file !#$

현재 라인에서 마지막 Arg를 잡습니다.

많은 사람들이 다음을 언급했습니다 -영형 옵션. 여기 남자 페이지 부분이 있습니다.

Man Page에서 :

   -o output-file
          Write output to output-file instead of to the  standard  output.
          If  output-file  is  one of the input files, sort copies it to a
          temporary file before sorting and writing the output to  output-
          file.

이것은 메모리 제한이 매우 높지만 AWK를 사용하여 중간 데이터를 메모리에 저장 한 다음 다시 작성할 수 있습니다.

uniq temp.txt | awk '{line[i++] = $0}END{for(j=0;j<i;j++){print line[j]}}' > temp.txt

대안 sponge 더 일반적인 sed:

sed -ni r<(command file) file

모든 명령에 대해 작동합니다 (sort, uniq, tac, ...) 그리고 잘 알려진 것을 사용합니다 sed'에스 -i 옵션 (파일 편집).

경고: 노력하다 command file 먼저 파일 편집은 본질적으로 안전하지 않기 때문입니다.


설명

첫째, 당신은 말하고 있습니다 sed (원본) 라인을 인쇄하지 않음 (-n 옵션), 그리고의 도움으로 sed'에스 r 명령 그리고 bash'에스 프로세스 대체, 생성 된 내용 <(command file) 저장된 출력이 될 것입니다 제자리에.


물건을 더 쉽게 만듭니다

이 솔루션을 함수로 랩핑 할 수 있습니다.

ip_cmd() { # in place command
    CMD=${1:?You must specify a command}
    FILE=${2:?You must specify a file}
    sed -ni r<("$CMD" "$FILE") "$FILE"
}

예시

$ cat file
d
b
c
b
a

$ ip_cmd sort file
$ cat file
a
b
b
c
d

$ ip_cmd uniq file
$ cat file
a
b
c
d

$ ip_cmd tac file
$ cat file
d
c
b
a

$ ip_cmd
bash: 1: You must specify a command
$ ip_cmd uniq
bash: 2: You must specify a file

인수를 사용하십시오 --output= 또는 -o

FreeBSD에서 방금 시도했습니다.

sort temp.txt -otemp.txt

추가하려면 uniq 기능, 단점은 다음과 같습니다.

sort inputfile | uniq | sort -o inputfile

비회적 편집자를 읽고, ex.

당신이 사용을 고집한다면 sort 프로그램, 중간 파일을 사용해야합니다. sort 메모리를 정렬 할 수있는 옵션이 있습니다. STDIN/STDOUT의 다른 트릭은 Sort의 Stdin의 버퍼 크기가 전체 파일에 맞을 정도로 크지 않다는 것을 보장 할 수 없다면 실패합니다.

편집 : 부끄러워. sort temp.txt -o temp.txt 훌륭하게 작동합니다.

다른 해결책 :

uniq file 1<> file
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top