2010-08-17 4 views
0

나는 한 무리의 파일, 일부 텍스트, 바이너리, 일관된 이름 지정이없는 디렉토리를 가지고있다. 텍스트 파일에서만 문자열을 검색하고 바꿉니다.텍스트 파일 만 검색하고 바꾸는 방법은 무엇입니까?

perl -i -pne 's#/some/text/to/replace#/replacement/text#' * 

-i 옵션을 제거하고 바이너리 파일이 잡힐 것을 볼 수 있습니다 : 그래서 나는 갔다. 바이너리 파일을 건너 뛰기 위해이 one-liner를 어떻게 수정합니까? ack을 남용

+1

먼저 텍스트와 이진이 무엇을 의미하는지 정의해야합니다. "텍스트"의 정의가 "31-127 사이의 문자 만 포함"합니까? 그렇다면,'''대신에''find ''라는 프로그램과 다른 프로그램이 필요합니다. 실제로 Perl 코드를 변경하는 것이 아닙니다. 어떤 파일이 glob 된 것인가하는 문제입니다. – mfontani

+1

mfontani, Perl은 이미 텍스트 파일을 구성하는 요소에 대한 완벽한 개념을 가지고 있습니다. – daxim

+0

@ daxim : 'cromulent'+1 +1 – dawg

답변

2

음, 이것은 모두 텍스트 파일의 정의가 무엇인지에 근거합니다. 그래서

perl -i -pne 'BEGIN{@ARGV=grep-T,@ARGV}s#regex#replacement#' * 

-T 테스트를 통과하지 않는 파일을 필터링됩니다 BEGIN 블록 : 펄 5는 파일 이름이나 파일 핸들이 (펄 5의 정의를 사용하여) 텍스트 파일 인 경우 당신에게 말할 것이다 그 -T filetest operator있다 그것들은 심지어 읽혀지지 않을 것입니다 (첫 번째 블록을 제외하고는 -T이 텍스트인지를 결정하기 위해 사용하기 때문입니다). perldoc을 가입일

-T 다음과 같이 -B 일 -X -f 스위치. 파일의 첫 번째 블록 정도는 이상한 제어 코드 또는 높은 비트가 설정된 문자와 같은 이상한 문자가 있는지 검사됩니다. 너무 많은 이상한 문자 (> 30 %)가 발견되면 -B 파일입니다. 그렇지 않으면 -T 파일입니다. 또한 첫 번째 블록에 0 바이트를 포함하는 파일은 이진 파일로 간주됩니다. 파일 핸들에서 -T 또는 -B를 사용하면 첫 번째 블록이 아닌 현재 IO 버퍼가 검사됩니다. -T와 -B는 빈 파일이나 파일 핸들을 테스트 할 때 EOF에있는 파일에 대해 true를 반환합니다. -T 테스트를 수행하기 위해 파일을 읽어야하기 때문에 대부분의 경우 -f $ 파일 & & -T $ 파일을 제외하고는 다음과 같이 -f를 먼저 파일에 대해 사용하려고합니다.

3
ack -n --text --sort -f . | xargs perl -i -pne 's…' 

-T하여 자신의 솔루션을 쓰는 것보다 훨씬 더 빨리 간다.

+0

OP가 Windows 기반이 아니라는 사실을 알고 있습니까? – dawg

+0

Windows 사용자는 ['xargs'] (http://gnuwin32.sf.net/packages/findutils.htm)도 가질 수 있습니다. – daxim

+0

@drewk 'cmd'가 작은 따옴표로 묶인 문자열을 좋아하지 않으므로 OP가 아마 윈도우 기반이 아닙니다. OP가 Windows에서 Cygwin을 사용하는 것이 가능하지만이 경우 OPEN은 xargs를 갖습니다. –

관련 문제