수많은 HTML 파일에서 문자열을 찾고 바꾸는 가장 빠른 방법

수많은 HTML 파일에서 문자열을 찾고 바꾸는 가장 빠른 방법

나는 많은 HTML 파일을 갖고 있는데, 모두 하나의 전체 폴더에 포함된 여러 폴더에 중첩되어 있습니다. 각 HTML 파일에서 교체해야 합니다.

/contact/index.html

그리고

/contact/index.php

명령줄에서 이 작업을 쉽게 수행할 수 있는 방법이 있습니까?

답변1

find예, GNU 및 GNU가 있는 경우 sed상위 폴더에서 다음을 시도하십시오.

find . -type f \( -iname "*.htm" -o -iname "*.html" \) -exec sed -i.bak 's#/contact/index\.html#/contact/index.php#' '{}' +

.html이름이 or .HTML또는 .htmor .HTM(또는 .HtM...) 로 끝나는 모든 파일을 찾아 sed다음 명령을 실행합니다.

sed -i.bak 's#/contact/index\.html#/contact/index.php#g'

foo.htm이렇게 하면 원하는 교체가 이루어지고 이름이 원시 백업이 생성됩니다 foo.htm.bak. 백업이 필요하지 않은 경우 삭제하면 됩니다 .bak.


세부 사항:

find분명히 이 명령은 파일이나 폴더를 찾습니다. 해당 구문은 매우 복잡할 수 있으며 man page아래 복사된 일부 구문에 자세히 설명되어 있습니다.

일반적인 형식은 입니다 find [where] [what]. 위에 제공된 예에서 where.현재 디렉터리를 나타냅니다. 이것은 확장자가 비슷하거나 유사한 모든 파일 what이므로 다음 을 사용하고 있습니다.htmliname

   -iname pattern
          Like -name, but the match is case insensitive.
          For example,  the  patterns  `fo*'  and  `F??'
          match  the  file  names  `Foo',  `FOO', `foo',
          `fOo', etc.   

그러나 나는 둘 다 일치하기를 원하므로 html해당 플래그를 htm사용합니다 -o. 이는 다음을 의미합니다.

  expr1 -o expr2
          Or; expr2 is not evaluated if expr1 is true.

이러한 구조는 괄호로 그룹화해야 합니다 ( ). 그러나 다음이 필요합니다.탈출하다우리가 사용하는 쉘에서 \(\).

마법은 다음 -exec부분에서 발생합니다.

   -exec command ;
          Execute command; true if 0 status is returned.
          All following arguments to find are  taken  to
          be  arguments to the command until an argument
          consisting of `;' is encountered.  The  string
          `{}'  is  replaced  by  the  current file name
          being processed everywhere it  occurs  in  the
          arguments  to  the  command, not just in argu‐
          ments where it is alone, as in  some  versions
          of  find.   [...] The specified command is
          run once for each matched file.   The  command
          is executed in the starting directory.   There
          are unavoidable security problems  surrounding
          use  of  the  -exec action; you should use the
          -execdir option instead.

즉, 이와 같은 명령이 주어지면 -exec ls {}설정 find한 기준과 일치하는 모든 파일을 찾아 반복하고 {}현재 파일 이름으로 바꾸고 주어진 명령을 실행합니다. 또한 end call +대신 사용합니다. 이렇게 하면 가능한 적은 수의 명령을 실행하려고 시도하게 됩니다 . 이는 수천 개의 파일이 없는 한 작은 최적화일 뿐이며 이는 중요할 수 있습니다.\;execfind

   -exec command {} +
          This variant of  the  -exec  action  runs  the
          specified  command  on the selected files, but
          the command line is built  by  appending  each
          selected  file name at the end; the total num‐
          ber of invocations of the command will be much
          less  than  the  number of matched files.  The
          command line is built in  much  the  same  way
          that xargs builds its command lines.  Only one
          instance of `{}' is allowed  within  the  com‐
          mand.  The command is executed in the starting
          directory.

마지막으로, sed파일의 각 줄에 지정한 명령을 적용하는 명령줄 텍스트 스트림 편집기가 있습니다. 이 경우 명령은 교체이며 기본 형식은 다음과 같습니다.

s#pattern#replacement#flags

구분 기호( #)는 임의의 특수 문자일 수 있으며 전통적으로 그렇습니다 . 그렇지 않으면 이스케이프해야 하기 때문에 ChrisDown이 그의 대답에 사용하기로 선택했습니다 /. 이것은 둘 다 동일합니다.#/|

답변2

GNU가 있다고 가정합니다 sed.

find -iname '*.html' -type f -exec sed -i 's|/contact/index\.html|/contact/index.php|g' {} +

관련 정보