sed를 사용하여 한 파일의 내용을 다른 파일로 복사

sed를 사용하여 한 파일의 내용을 다른 파일로 복사

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하고 sedGNU가 되는 경우 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는 "내부" 편집을 수행하지 않습니다(즉, -iRaku에는 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

관련 정보