대체를 수행하려는 파일 목록과 해당 줄 번호가 있습니다.
s/LOG.error/LOG.warn
이런 일이 발생할 수 있고 해당 라인을 방해하고 싶지 않은 다른 장소가 있습니다. find와 sed를 사용하여 이 작업을 어떻게 수행할 수 있나요?
파일 형식은 다음과 같습니다.
FooBar.java 125
FooBar.java 180
FooBar2.java 128
방법을 검색하다가 발견한 내용은 다음과 같습니다.
cat filenames.txt | xargs sed -i '<get-line-number-here>s/LOG.error/LOG.warn' <get-file-name-here>
답변1
파일을 대상 파일별로 파티션으로 분할하고 sed -i
각 파일에 대해 개별적으로 수행해야 합니다. 파일 이름과 줄 번호가 파일 이름별로 오름차순으로 그룹화되어 있다고 가정하면 다음과 같이 할 수 있습니다.
awk '$1 != prev { if (prev) print "\047 " prev;
prev=$1;
printf "sed -i \047" }
{ print $2 "s/LOG\\.error/LOG.warn/" }
END { if (prev) print "\047 " prev }' filenames.txt | sh
이것은 첫 번째 열의 파일 이름이 단일 토큰이 아닌 경우 흥미롭고 위험한 방식으로 침입할 수 있는 빠르고 더러운 해킹입니다.
기본적으로 텍스트 파일을 일련의 sed
스크립트로 리팩터링합니다. 따라서 귀하의 예는 다음과 같이 바뀔 것입니다.
sed -i '125s/LOG\.error/LOG.warn
180s/LOG\.error/LOG.warn/
' FooBar.java
sed -i '128s/LOG\.error/LOG.warn/
' FooBar2.java
여러분이 주목하게 될 것은 각 파일에 대해 sh
하나의 스크립트를 포함하는 스크립트 입니다.sed
*BSD 플랫폼(Mac OS 포함)을 사용하는 경우 주변 쉘 인용을 방해하지 않고 작은따옴표를 적절하게 포함하려면(전체 줄이 (sic) 이 되도록 ) Awk에서 플랫폼 sed -i
으로 변경해야 합니다 .sed -i ''
"sed -i \047\047"
printf "sed -i \047\047 \047" }