답변:
왜 vim을 사용하지 않습니까?
vim에서 모든 파일 열기
vim $(find . -type f)
또는 관련 파일 만 엽니 다 (Caleb에서 제안한대로)
vim $(grep 'from' . -Rl)
그런 다음 모든 버퍼에서 바꾸기를 실행하십시오.
:bufdo %s/from/to/gc | update
당신은 또한 그것을 할 수 sed
있지만 내 sed 지식은 제한되어 있습니다.
grep
대신 대신 사용하여 현재 버퍼에서 모든 파일을 열지 않으면 서 속도를 높일 수 있습니다 find
. vim $(grep 'from' . -Rl)
-l -pe
인수 ( -i
) 로 전달 된 파일에 대해 줄 단위로 교체 ( ) 를 수행하도록 지시하는 작은 Perl 스크립트로 조잡한 작업을 수행 할 수 있습니다 .
perl -i -l -pe '
if (/from/) { # is the source text present on this line?
printf STDERR ("%s: %s [y/N]? ", $ARGV, $_); # display a prompt
$r=<STDIN>; # read user response
if ($r =~ /^[Yy]/) { # if user entered Y:
s/from/to/g; # replace all occurences on this line
}' /path/to/files
가능한 개선 사항은 프롬프트의 일부를 색칠하고 "현재 파일에서 발생하는 모든 항목 바꾸기"와 같은 항목을 지원하는 것입니다. 줄마다 각 항목에 대해 별도로 프롬프트를 표시하는 것이 더 어렵습니다.
두 번째 부분은 파일과 일치합니다. 너무 많은 파일이 포함되어 있지 않고 zsh를 실행중인 경우 현재 디렉토리 및 해당 서브 디렉토리의 모든 파일을 재귀 적으로 일치시킬 수 있습니다.
perl -i -l -pe '…' **/*(.)
쉘이 bash ≥4이면을 실행할 수 perl … **/*
있지만 sed는 디렉토리에서 실행하려고 시도하고 실패하기 때문에 잘못된 오류 메시지를 생성합니다. C 파일과 같은 파일 세트에서만 교체를 수행하려는 경우 일치를 제한 할 수 있습니다 (bash ≥4 또는 zsh에서 작동).
perl -i -l -pe '…' **/*.[hc]
교체 할 파일을보다 세밀하게 제어해야하거나 쉘에 재귀 디렉토리 일치 구문 **
이 없거나 파일이 너무 많아서 "명령 줄이 너무 깁니다"오류가 발생하면을 사용하십시오 find
. 예를 들어, 이름이 *.h
있거나 *.c
현재 디렉토리 및 해당 서브 디렉토리에있는 모든 파일 (이전 시스템의 경우)을 바꾸 려면 줄의 끝 \;
대신에 사용해야 합니다 +
( +
양식이 더 빠르지 만 모든 곳에서 사용할 수는 없음).
find . -type f -name '*.[hc]' -exec perl -i -l -pe '…' {} +
즉, 상호 작용이 필요한 경우 대화 형 편집기를 사용합니다. Gert는 Vim 에서이 방법을 보여 주었지만 검색하려는 모든 파일을 열어야하지만 많은 경우 문제가 될 수 있습니다.
Emacs에서는 다음과 같은 방법으로이를 수행 할 수 있습니다.
M-x find-name-dired
(최상위 디렉토리 M-x find-dired
지정 ) 또는 (임의의 find
명령 행 지정 )으로 파일 이름을 수집하십시오 .t
모든 파일을 표시 한 다음 Q
( dired-do-query-replace-regexp
) 을 눌러 표시된 파일에 대한 프롬프트로 교체를 수행하십시오.sdiff
여기 ( http://www.gnu.org/software/diffutils/manual/diffutils.html#Invoking-sdiff 참조 )가 유용 할 수 있습니다. 그것으로 당신은 대화식 패치를 할 수 있습니다. 따라서 대체 작업을 사용하여 만든 임시 파일로 파일을 작성 sed
하는 것이 가능한 해결책 일 수 있습니다.
# use file descriptor 3 to still allow use of stdin
while IFS= read -r -d '' file <&3; do
# write the result of the replacement into a temporary file
sed -r 's/something/something_else/g' -- "$file" > replacer_tmp
if cmp -s -- "$file" replacer_tmp; then
continue; # nothing was replaced
fi
echo "There is something to replace in '$file'! Starting interactive diff."
echo
sdiff -o "$file" -s -d -- "$file" replacer_tmp
echo
done 3< <(find . -type f -print0)
(POSIX 이외의 프로세스 대체를 사용하고 read -d
예를 들어 지원되는 파일 루프 bash
)
s/from/to/g
않고 형식 지정 결함 으로 명령을 읽었습니다 (Markdown으로 할 수는 없습니다. 및 HTML 태그).s/from/to/gc
c
<code>
<strong>