고유 한 정렬 : 출력을 동일한 파일로 리디렉션


14

파이프 출력을 처리 된 것과 동일한 파일에 저장하는 짧은 방법이 있습니까? 예를 들어, 이것은 내가 실제로하고있는 일입니다.

$ cat filename | sort | uniq > result
$ rm -f filename
$ mv result filename

한 줄로 수행 할 수있는 방법이 있는지 궁금합니다 (&&를 사용하여 해당 명령을 추가하지 않음)

이것은 방법이 아니지만 아이디어를 얻는 것입니다.

$ cat filename | sort | uniq > filename

2
echo $(cat filename | sort | uniq > result) > filename또는 뭔가 ? 지나 가서 시도 할 시간이 없습니다.
MrVaykadji

답변:


18

moreutils 패키지 sponge에서 사용할 수 있습니다 :

LC_ALL=C sort -u filename | sponge filename

당신은 또한에 파이프를하지 않아도 uniq언제부터, sort-u독특한 라인 옵션 정렬.

UTF-8 로켈와 GNU 시스템에서,주의 sort -u또는 sort | uniq당신에게 독특한 라인을 제공하지 않았지만, 현재 로켈에서 정렬 같은 라인의 순서에서 첫 번째.

$ printf '%b\n' '\U2460' '\U2461' | LC_ALL=en_US.utf8 sort | LC_ALL=en_US.utf8 uniq

당신에게만주었습니다 . 로케일을 C로 변경하면 바이트 값을 기준으로 정렬 순서가 강제됩니다.

$ export LC_ALL=C
$ printf '%b\n' '\U2460' '\U2461' | LC_ALL=C sort | LC_ALL=C uniq


12

당신은 같은 여분의 명령이 필요하지 않습니다 catuniq도 사용하지 않고 rm명령 mv제거하고 파일 이름을 이름 바꾸기 명령을. 간단한 명령 만 사용하십시오.

sort -u filename -o filename


 -u, --unique
        with -c, check for strict ordering; without -c, output only  the
        first of an equal run

 -o, --output=FILE
        write result to FILE instead of standard output

어떻게 작동합니까?

sort명령은 파일 이름을 정렬하고 -u옵션을 사용 하여 파일 에서 중복 행을 제거합니다. 그런 다음 -o옵션을 사용하면 적절한 방법으로 출력을 동일한 파일에 씁니다.


3
sort실행 중 시스템 충돌이 발생하면 원본 파일이 느슨해집니다.
cuonglm

@Gnouc 그래서, 이것은 불행의 끝입니다 !! : '(
αғsнιη

1
감사! 이 예에서 특히 '정렬'을 사용하면 그렇게해야합니다. 그러나 나는 일반적인 경우에 대해 생각하고있었습니다. @Gnouc, haha ​​당신에게 그런 일이 일어나지 않았다고 생각할 방법이 없습니다.
whitenoisedb

3

실제로 동일한 파일에서 동시에 읽고 쓰는 중이므로 제시된 예제 (아래)가 작동하지 않습니다.

$ cat filename | sort | uniq > filename

파이프 또는 리디렉션의 아이디어는 각 파이프 또는 리디렉션의 왼쪽과 오른쪽에있는 명령이 동시에 실행된다는 것입니다. 오른쪽의 명령은 왼쪽의 명령이 계속 실행되는 동안 왼쪽의 명령에서 정보를 전달할 때 정보를 처리합니다.

시나리오가 작동하려면 파일에 쓰는 명령이 시작되기 전에 파일에서 읽는 명령이 완료되어야합니다. 이 작업을 수행하려면 먼저 출력을 임시 위치로 리디렉션 한 다음 완료되면 임시 위치에서 파일로 다시 보내야합니다.

이 작업을 수행하는 더 좋은 방법은 기본적으로 이전 예와 같습니다. 여기서 임시 파일로 리디렉션 한 다음 해당 파일의 이름을 다시 원래 이름으로 변경합니다 (이동은 기존 대상을 삭제하므로 파일을 먼저 삭제할 필요가 없다는 점을 제외하고) .

$ cat filename | sort | uniq > result
$ mv -f result filename

데이터가 한 번에 메모리에 모두 들어갈 수있을 정도로 작을 때만 작동한다는 점을 제외하고 문자열 변수에 저장할 수도 있습니다.


누군가가 제안 편집에 넣어, 당신은 변경할 수 cat filename | sort에 그냥 sort filename- cat여기 필요하지 않습니다.
thomasrutter

아래의 예는 그렇게하지 못했습니다. 설명해 주셔서 감사합니다. cat이 경우 불필요 할 수 있지만 리디렉션 부분에 중점을 두었습니다.
whitenoisedb

1
아래 예제가 작동하지 않는 이유 를 설명하고있었습니다 . 나는 그것이 작동하지 않는다는 것을 알고 있다는 것을 알고 있습니다.
thomasrutter

설명해 주셔서 감사합니다! 사실 나는 실제로 무슨 일이 있었는지 몰랐습니다.
whitenoisedb

2

다음 tee명령을 사용할 수 있습니다 .

sort -u filename | tee filename > /dev/null

tee명령은 표준 입력에서 읽고 표준 출력 파일에 씁니다 .


2
이것은 나를 위해 작동하지 않습니다.
pjvandehaar


이것은 않는 나를 위해 일을. 예를 들어, 줄을 파일의 맨 아래로 옮기려면 : (cat ~/file | grep -v 3662 ; printentry 3662) | tee ~/file > /dev/null작동합니다. 원래의 게시물과 마찬가지로이 그냥 경우 작동하지 않습니다 > ~/file를 빼고 tee. sort -o file동일한 파이프를 계속 사용하지 않고 명명 된 파일에 쓰는 Tee는 여기와 비슷해 보입니다 .
Joshua Goldberg

기다려, 미안 나는 경험적으로 이것은 @Steven의 링크에 설명 된 것처럼 예기치 않게 데이터를 잃을 것입니다. 9 줄에 숫자 1..9로 파일을 만듭니다. 다음은 여러 번 작동 한 다음 때때로 파일에서 모든 데이터를 제거합니다. (cat x | grep -v 7 ; echo 7) | tee x > /dev/null; cat x 임시 파일 mv또는 @Steven의 링크에서 해결책을 권장합니다 .
Joshua Goldberg

@JoshuaGoldberg이 페이지에서 내 답변을 보셨습니까?
Steven Penny

0

Ex 모드에서 Vim을 사용할 수 있습니다 :

ex -sc 'sort u|x' filename
  1. sort u 독특한 정렬

  2. x 변경 사항이 있으면 작성하고 종료하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.