bash를 사용하여 파일 (Argument)을 편집하는 명령을 어떻게 실행합니까?
-
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