Alma Linux 8에서 sed를 사용하여 한 파일의 모든 텍스트를 다른 파일로 복사하고 싶습니다. 예를 들어 첫 번째 파일 old.txt
은 다음과 같습니다.
192.168.0.1
192.168.0.2
192.168.0.3
192.168.0.4
192.168.0.5
...
또 다른 파일은 new.txt
다음과 같습니다:
192.168.0.1
192.168.0.2
192.168.0.3
항목을 복사하고 싶지만 복제하지는 old.txt
않습니다 new.txt
. 예상 출력 new.txt
:
192.168.0.1
192.168.0.2
192.168.0.3
192.168.0.4
192.168.0.5
어떻게 해야 하나요?
답변1
고유성 제약 조건이 있는 간단한 순서를 제외하고는 아무것도 필요하지 않습니다.
sort -u old.txt new.txt >new.txt.tmp &&
mv -f new.txt.tmp new.txt
rm -f new.txt.tmp
나는 보았다POSIXsort
능력을 정의한다입력 파일에 직접 쓰기, 따라서 이 작업도 수행할 수 있지만 오류 발생 시 얼마나 강력한지 테스트하지 않았습니다(이전 버전에서는 손실 없이 원본을 유지하거나 새 버전으로 교체할 수 있음).
sort -o new.txt -u old.txt new.txt
또는 를 사용할 수 있습니다 awk
. 이 버전은 첫 번째 파일부터 시작하여 파일의 줄 순서를 변경하지 않고 유지하고 후속 파일에만 새 줄을 추가합니다.
awk '
FNR<NR && h[$0] { next } # Skip seen lines in secondary files
{ h[$0]=1; print } # Record the line and output it
' new.txt old.txt
설명을 추가할 수 있도록 줄로 나누었습니다. 이를 제거하면 한 줄로 축소될 수 있지만 일반적으로 읽기 쉬운 코드를 작성하는 것이 더 좋습니다. 의도적으로 첫 번째 파일을 삭제하지 않습니다 new.txt
.
awk '! h[$0]++' new.txt old.txt
이는 표시되는 각 행의 연관 배열 값을 증가시키지만 값이 0(설정되지 않음)인 경우에만 인쇄합니다.
답변2
sort
다른 답변에 따라 명령을 사용할 수 있지만 출력 파일을 명시적으로 언급하고 제자리에서 정렬을 수행할 수 있습니다(중간 파일 없음).
sort -u -o new.txt old.txt new.txt
가능한 방법 중 하나 awk
:
awk -i inplace '{z[$0]=1} END{for( i in z) print i}' new.txt old.txt
입력 파일 중 하나 또는 둘 다 매우 길면 많은 메모리를 "먹을" 수 있습니다. inplace
출력을 유지합니다new.txt
답변3
이것은 실제로 작동하지 않지만 sed
사용해야 sed
하고 sed
GNU가 되는 경우 sed
다음을 수행할 수 있습니다.
sed -E '
:1; $!{N;b1}
:2; s/^((.*)$(.|\n)*)\n\2$/\1/m; t2
' new.txt old.txt
어디:
:1; $!{N;b1}
전체 입력(패턴 공간의 두 파일)을 루프에 로드합니다.:2; s/^((.*)$(.|\n)*)\n\1$/\1/m; t2
루프의 이 패턴 공간에서 중복 행을 제거합니다.
현재 위치에서 수정 하려면 new.txt
다음을 수행할 수 있습니다.
sed -nE '
:1; $!{N;b1}
:2; s/^((.*)$(.|\n)*)\n\1$/\1/m; t2
w new.txt
' new.txt old.txt
답변4
사용행복하다(이전 Perl_6)
~$ raku -e '.put for lines.unique;' old.txt new.txt > tmp.txt
Raku는 명령줄에서 파일을 읽기 위해 작업 루틴을 사용합니다 lines
. 따라서 두 개의 파일을 읽고 >
하나의 파일로 리디렉션 할 수 있습니다 tmp.txt
. 그런 다음 결과가 확인되면 tmp.txt
파일을 다시 복사 할 수 있습니다 new.txt
.
Raku는 "내부" 편집을 수행하지 않습니다(즉, -i
Raku에는 Perl의 명령줄 플래그와 동등한 기능이 없습니다).
입력 예 old.txt
:
192.168.0.1
192.168.0.2
192.168.0.3
192.168.0.4
192.168.0.5
입력 예 new.txt
:
192.168.0.1
192.168.0.2
192.168.0.3
출력 예 tmp.txt
:
192.168.0.1
192.168.0.2
192.168.0.3
192.168.0.4
192.168.0.5
Raku 루틴의 한 가지 장점 은 매개변수 unique
를 사용한다는 것입니다 as
. 즉, 입력 라인의 일부만 비교에 사용됩니다 unique
. 이러한 옵션을 사용하면 (예를 들어) 전체 경로에서 고유한 파일 이름을 복구하고 다른 디렉터리에서 중복된 이름을 삭제할 수 있습니다. 자세한 내용은 아래 첫 번째 SO 링크를 참조하세요.
https://unix.stackexchange.com/a/720574/227738
https://docs.raku.org/routine/unique
https://raku.org