Bash 스크립트는 조건이 충족되면 모든 파일의 시작 부분에 텍스트를 넣습니다.

Bash 스크립트는 조건이 충족되면 모든 파일의 시작 부분에 텍스트를 넣습니다.

다음과 같은 경우에만 모든 하위 디렉터리의 모든 파일 시작 부분에 텍스트를 넣는 bash 스크립트를 작성하려고 합니다.

  1. 파일에 텍스트가 포함되어 있지 않습니다.
  2. 파일에는 회사 이름, River라는 단어 또는 Systems라는 단어가 포함되어 있습니다.

이것이 내가 지금까지 가지고 있는 것입니다:

for i in $(find -name *.cpp -type f -print)
do 
if ! grep -r 'This document contains technical data' $i && grep -r 'company name' $1 || grep-r 'River' $i || grep -r 'Systems' $i; then
#add text

이제 키워드가 포함되지 않은 파일은 예상대로 변경되지 않지만 이미 텍스트와 키워드가 포함된 파일의 경우에는 변경됩니다. || 주위에 [] 문을 사용해 보았지만 결과는 동일합니다. 어떤 제안이 있으십니까?

답변1

find . -name '*.cpp' -type f \
  ! -exec grep -qF 'This document contains technical data' {} ';' \
  -exec grep -qFe River -e 'company name' -e Systems {} ';' \
  -exec sed -i '1i\
This document contains technical data' {} +

( FreeBSD/macos' sed -i로 대체됨 )sed -i ''sed

grep또는 GNU를 사용하면 GNU가 더 효율적입니다 xargs.

grep --include='*.cpp' -rFlZ -e River -e 'company name' -e Systems . |
  xargs -r0 grep -FLZ 'This document contains technical data' |
  xargs -r0 sed -i '1i\
This document contains technical data.'

시도에 대한 몇 가지 참고 사항:

  • find -print출력을 사후 처리할 수 없습니다..
  • 매개변수 확장은 다음에서 인용되어야 합니다.bash
  • -r(GNU 확장)재귀적grep은 자체 작업 외에 다른 작업도 grep수행 하려면 디렉터리를 ping할 때만 사용하면 됩니다(그래서 디렉터리에서 파일을 찾은 다음 해당 파일에서 패턴을 찾습니다).findgrep
  • *특수문자다껍데기, 거기에서 와일드카드가 트리거됩니다. *.cpp에 리터럴을 전달할 수 있도록 인용되어 있는지 확인해야 합니다 find.
  • 일치하는 모든 행을 확인하지 않고 파일에서 패턴이 일치할 수 있는지 여부를 확인하려면 이 옵션을 사용하십시오 -q. 인쇄를 건너뛸 뿐만 아니라 grep더 이상 첫 번째 일치 항목을 확인하지 않으므로 더 효율적입니다. -l-L(GNU 확장)은 동일한 최적화를 갖습니다. 전자는 패턴이 발견되면 파일 경로를 인쇄하고, 후자는 패턴을 발견하지 못하면 파일 경로를 인쇄합니다.
  • 고정 문자열을 검색하려면 F(정규식 일치를 수행하는 대신) 이 -F옵션을 사용하면 정규식 연산자를 이스케이프할 필요가 없습니다.
  • , 를 grep foo file || grep bar file사용 하지 않고도 하나의 패턴에서 여러 패턴을 찾을 수 있습니다 .find'(' -exec grep -q foo {} ';' -o -exec grep -q bar {} ';' ')'grep또는한 번에 세련되게 grep -e foo -e bar file또는다른 방법.
  • or 와도 grep -F River일치합니다 Riverside. 일치하는 옵션만 추가할 수 있습니다.WindRiver-w모두단어(단어는 숫자나 밑줄 등 단어가 아닌 문자로 구분되어야 하며, 단어가 아닌 문자는 기타 문자입니다).

답변2

&&를 다른 if 문으로 바꾸면 다음과 같이 작동합니다.

if ! grep -r 'This document contains technical data' $i; then
  if grep -r 'company name' $1 || grep-r 'River' $i || grep -r 'Systems' $i; then
     #add text
  fi
fi

관련 정보