디렉토리의 모든 .fasta 파일에서 151-154행을 제거하고 싶습니다. 노력하고있어
find . -type f -exec sed -i.fix '151,154d' '{}' '+'
하지만 다른 400개 파일이 아닌 첫 번째 파일에서만 실행됩니다.
답변1
-i
비표준 sed
옵션입니다. 그것은 에서 온다 perl
. GNU와 FreeBSD는 sed
동작을 에뮬레이트하기 위해 2001년 말과 2002년 초에 독립적으로 추가되었지만 인터페이스는 다릅니다. 더 많은 변경 사항(특히 원본 파일 메타데이터가 유지되는 정도와 관련하여)이 있었기 때문에 더 많은 구현이 이루어졌습니다.-i
perl
에서는 perl
다음을 수행합니다.
perl -ni.back -e 'print unless $. == 151..154' file
$.
현재 줄 번호입니다현재 입력 파일 핸들. /를 사용 하면 <>
차례로 인수로 전달된 파일마다 파일 핸들이 열리지만, 각 파일 간에는 닫히지 않으므로 각 파일 간에 재설정되지 않습니다. 이렇게 하려면 다음이 필요합니다.-n
ARGV
ARGV
$.
perl -ni.back -e '
print unless $. == 151..154;
close ARGV if eof' file1 file2
GNU는 à la 옵션 (2001-09-25에 추가되었지만 1년 후(3.95)까지 출시되지 않음)을 추가한 sed
첫 번째 구현(AFAIK)이었습니다. 이 옵션은 각 파일 사이의 줄 번호를 재설정합니다( 다른 GNU 확장을 암시함). .-i
perl
-s
FreeBSD다른 일을 했어. GNU의 원래 API와 FreeBSD의 주요 차이점은 -i
FreeBSD에서는 매개변수가 필수인 반면, GNU에서는 에서 sed
와 같이 선택사항이라는 것입니다 perl
. FreeBSD에서는 처음에는 각 파일 사이의 줄 번호가 재설정되지 않습니다.
2007년,FreeBSD는 sed
두 번째 점에서 GNU와 일치합니다.. 각 파일 사이의 줄 번호가 재설정 -I
되었으며 -i
.
-i
비지박스(Busybox), NetBSD, OpenBSD와 같은 다른 구현에 의해 훨씬 나중에 sed
지원이 추가되었지만 sed
두 가지 점 모두에서 GNU와 일치합니다.
macOS는 sed
이전 버전의 FreeBSD를 기반으로 하므로 현재 이전 버전의 FreeBSD와 동일하게 작동하는 유일한 구현일 수 있으며 현재 사용 중인 구현일 수도 있습니다.
따라서 여기서 다음을 사용해야 합니다 perl
.
find . -type f ! -name '*.back' -exec perl -ni.back -ne '
print unless $. == 151..154;
close ARGV if eof' {} +
또는 sed
각 파일에 대해 하나씩 호출하십시오.
find . -type f ! -name '*.back' -exec sed -i.back 151,154d {} \;
sed
GNU 또는 GNU를 설치하고 사용하거나 awk
( 대신 -i /usr/share/awk/inplace.awk
1을 사용하고 일치 ) 또는FNR
NR
ed
/ ex
방법에 따라.
^사용하지 마세요-i inplace
현재 작업 디렉터리(as or)에서 확장 기능을 먼저 gawk
로드 하려고 하면 누군가가 해당 디렉터리에 악성 코드를 심었을 수 있습니다. 시스템과 함께 제공되는 확장 프로그램 의 경로 는 다를 수 있습니다. 출력을 참조하세요.inplace
inplace
inplace.awk
inplace
gawk
gawk 'BEGIN{print ENVIRON["AWKPATH"]}'
답변2
이 답변은 실제 내부 편집이 아니기 때문에 ex
대신 사용됩니다. 임시 파일에 쓴 다음 이름을 바꾸어 원본 파일을 대체하므로 inode 번호가 변경됩니다. 이렇게 하면 COW 파일 시스템(예: btrfs 또는 zfs)의 모든 하드 링크와 스냅샷 및 파일의 inode 번호에 의존하는 모든 항목이 손상됩니다. 다른 구현 / 옵션( 's 옵션 포함 ) 을 사용하는 대부분의 다른 일반적인 명령에서도 마찬가지입니다.sed -i
sed -i
-i
--in-place
perl
-i
find . -type f -exec sh -c 'for f in "$@" ; do
cp -a "$f" "$f.fix"
printf "%s\n" 151,154d x | ex -s -- "$f"
done' sh {} +
이 분기는 sh
발견된 파일 목록을 처리하는 데 사용됩니다 find
.
이 sh
프로세스에서는 먼저 원본 파일의 백업 복사본을 만든 다음( 타임스탬프 및 권한과 같은 모든 속성을 보존하기 위해 GNU 옵션을 사용) 호출하여 cp
파일 을 편집합니다.-a
ex
위 파이프라인의 printf ... | ex ...
두 ex
명령(*)into 에서 ex
각 명령은 개행 문자로 구분됩니다. 첫 번째 명령은 151-154행을 삭제합니다. 두 번째( x
)는 ex
변경 사항을 파일에 쓰도록 지시합니다( ex
저장하라고 지시하지 않으면 기본적으로 저장하지 않고 종료됩니다). 변경 사항이 없으면 저장하지 않고 종료합니다. 와 동일한 명령입니다 x
.:x
vi
참고: 단일 입력 파일의 행 수가 154개 미만인 경우아니요이 파일이 변경됩니다.
이 -s
옵션은 ex
조용하고 진단 메시지를 인쇄하지 않도록 지시합니다.
파일 이름이 로 시작하는 경우 --
파일 이름 인수가 옵션으로 해석되지 않도록 합니다 . 이 명령으로 출력되는 모든 파일 이름 에는 접두사가 있으므로 여기서는 꼭 필요한 것은 아닙니다 . 그러나 이는 무해하며 알 수 없는 파일 이름을 처리할 때 좋은 습관입니다.ex
-
find
./
(*) ex
Command 는 command 와 거의 동일합니다 sed
. 알고 보니 오래전 ed
에는 sed
. 시각적 편집 모드가 추가되었지만 명령 모드 의 명령은 유지되었습니다 . 여기서 사용하는 모드인 비주얼 모드 없이 명령 모드 편집처럼 실행할 수도 있습니다 . 여전히 대부분은 복제품이지만 처음 작성된 이후 수십 년 동안 원본에 비해 약간의 개선(예: 명령)을 얻었습니다 .ed
vi
ed
vi
ed
:
vi
ex
ex
ed
x
ed
답변3
당신은 올바른 길을 가고 있습니다. 명령을 약간 편집하면 됩니다. exec 대신 xargs를 사용할 수도 있습니다. 작동하는 버전은 다음과 같습니다.
$ find . -type f | xargs -I{} sed -i '151,154d' {}