title=
텍스트 파일의 문자열 앞뒤에 공백이 나타나는 경우에만 sed를 사용하여 공백을 밑줄로 바꾸는 방법" "
예를 들어(텍스트 파일의 줄):
title="This is the title of my book" img=scr " </header><!-- .entry-header -->
title="Today is a beautiful day" img=scr " </header><!-- .entrrrrkkky-header -->
sed 후에 텍스트 파일 수정이 필요합니다.
title="This_is_the_title_of_my_book" img=scr " </header><!-- .entry-header -->
title="Today_is_a_beautiful_day" img=scr " </header><!-- .entrrrrkkky-header -->
기본적으로 문자열 뒤에 공백이 있는 경우에만 a가 대체됩니다 .
_
" "
title=
텍스트 파일의 이름은 임의적입니다.file.txt
답변1
루프에서 이 작업을 수행해야 합니다.
s/\(^.*title="[^" ]*\) \([^"]*".*$\)/\1_\2/
또는 (빠르게)
s/\(title="[^" ]*\) \([^"]*"\)/\1_\2/
또는 (아마도 다시 더 빨라질 것입니다. 왜 자신을 대체하기 위해 다른 일치 항목을 추가해야 합니까?!)
s/\(title="[^" ]*\) /\1_/
그리고 더 이상 변경 사항이 없을 때까지 sed의 테스트 및 분기 기능을 사용하여 대안을 다시 시도하세요. 이 명령에서 패턴의 요점은 첫 번째(나머지) 공백에서 줄을 분할하고 해당 공백을 밑줄로 바꾸는 것입니다.
다음은 스크립트입니다.
#!/bin/sh
sed -e ':loop' \
-e 's/\(title="[^" ]*\) \([^"]*"\)/\1_\2/' \
-e 't loop' <foo.in >foo.out
diff -u foo.in foo.out
원래 답변은 더 넓은 패턴을 사용했지만 @g-man은 이것이 필요하지 않다고 언급했습니다. 10Mb 파일의 sed 타이밍에서 볼 수 있듯이 속도가 더 느립니다(Debian 7에서 GNU sed로 테스트).
$ ./foo1
27.03user 0.01system 0:27.18elapsed 99%CPU (0avgtext+0avgdata 1104maxresident)k
0inputs+0outputs (0major+333minor)pagefaults 0swaps
9.54user 0.00system 0:09.60elapsed 99%CPU (0avgtext+0avgdata 972maxresident)k
0inputs+0outputs (0major+301minor)pagefaults 0swaps
OSX의 경우 차이는 그다지 크지 않습니다.
$ ./foo1
real 0m11.943s
user 0m11.897s
sys 0m0.024s
real 0m5.858s
user 0m5.839s
sys 0m0.014s
흥미롭게도 더 넓은 모드는 Solaris의 sed에서 작동하지 않습니다(그러나 더 짧은 모드는 작동합니다). BSD와 GNU는 모두 일치하지만 group 내 줄의 끝 \(
이나 \)
그룹 내 줄의 끝과 일치하지 않습니다. 마찬가지로 HPUX 11.31 및 AIX 7.1에서도 작동합니다.
POSIX sed는 BRE를 사용하며 그룹화 기능은 다음에서 제공됩니다.9.3.6 여러 문자를 일치시키는 BRE:
"\("
하위 표현식은 문자 쌍과 . 사이에 하위 표현식을 묶어서 BRE에서 정의할 수 있습니다"\)"
. 이러한 하위 표현식은 하위 표현식의 고정이 선택적 동작이 아닌 한 "(" 및 ")" 없이 일치하는 모든 항목과 일치해야 합니다.BRE 표현 앵커. 하위 표현식은 임의로 중첩될 수 있습니다.
9.3.8 BRE 표현 고정용어를 설명하세요.
BRE는 줄로 시작하거나 끝나는 일치하는 문자열로 제한될 수 있습니다. 이를 "앵커링"이라고 합니다.
따라서 표준 구현의 맥락에서 이는 Solaris의 알려진 제한 사항이며 sed
표준에서는 이를 "선택적" 동작으로 허용합니다.
추가 자료:
- 3.7 sed 마스터 명령(레이블과 루프 설명)