이 있는데 file1
패턴과 일치하는 행을 삭제해야 합니다. 하지만 삭제된 행을 다른 file2
.
sed '/zz/!d' file1 > file2
sed -i '/zz/d' file1
이 명령들을 하나로 결합하는 방법이 있습니까?
아니면 더 우아한 방법이 있습니까?
답변1
GNU Sed를 확인하세요.
sed -ni '/zz/!{p;b};w file2' file1
플래그는 이 순서대로 이루어져야 합니다 -ni
.
설명: d
명령을 사용하여 스크립트를 중지하는 대신 플래그(자동)를 설정하고 명령(현재 패턴 공간 인쇄)을 사용하여 -n
템플릿과 일치하지 않는 줄을 작성한 다음 스크립트 끝으로 이동합니다. 패턴과 일치하는 행은 패턴 공간을 파일에 쓰는 명령에 도달합니다.p
b
w
답변2
perl -pi -e 'select( /zz/ ? STDOUT : ARGVOUT )' file1 > file2
-i
file1의 내부 편집을 처리합니다. -p
Perl 프로그램을 실행한 후 라인을 인쇄합니다. 프로그램이 해야 할 일은 출력 위치를 선택하는 것뿐입니다. 이 경우 이는 ?:
select stdout을 사용하여 달성할 수 있습니다 ARGVOUT
(이것이 바로 이것이 -i
사용되는 것입니다).
답변3
아무것도 아닌 경우:
awk '/zz/{print >> "file2"; next} 1' file1 > tmp && mv tmp file1
임시 파일을 명시적으로 생성하고 싶지 않다면 다음을 사용하세요.GNU awk:
gawk -i inplace '/zz/{print >> "file2"; next} 1' file1
추가하는 대신 잘라내고 싶다면 >>
로 변경하세요.>
file2
답변4
perl
해당 플래그와 함께 사용 -i
하고 일치하는 행을 표준 출력으로 인쇄하여 파일로 리디렉션할 수 있습니다.
$ cat file1
asdasd
baba zzbabab
asdasd
sadkzzpasdad
$ perl -i -ne 'if(/zz/){ print STDOUT } else{ print }' file1 > file2
You could rewrite the above via a string form of eval where we construct
the above piece of perl code based on presence of zz:
$ perl -i -ne 'eval "print ".qw[STDOUT][!/zz/]' file1 > file2
$ cat file1
asdasd
asdasd
$ cat file2
baba zzbabab
sadkzzpasdad
Perl의 또 다른 접근 방식은 다음과 같습니다.
$ perl -pi -e 'print(STDOUT),s/.*//s if /zz/' file1 > file2
- 자동 인쇄 모드 사용
-p
- zz 라인을 표준 출력으로 인쇄한 다음, 패턴을 통해 파일 1에 다시 기록될 때 이를 지웁니다
-i
.