설명한 대로 Windows에서 Linux 드라이버로 변환하는 과정의 일부로 stdint.h
단어가 포함된 파일에 표준 C 패키지를 포함하려고 합니다.LARGE_INTEGER
여기데이터 유형의 경우. find 및 xargs에 대한 이전 스레드에 대해 알고 있습니다.여기그리고여기.
GNU 찾기 부분의 코드는 주로 다음을 기반으로 합니다.철사:
gfind /tmp/ -type f \
\( -name "*.h" -o -name "*.cpp" \) \
-exec ggrep -Pl "LARGE_INTEGER" {} +
의사코드 확장자도 포함하고 싶습니다. 또한 파일에 다음 단어가 포함되어야 합니다.LARGE_INTEGER
gfind /tmp/ -type f \
\( -name "*.h" -o -name "*.cpp" \) \
-and -exec ggrep -Pl "LARGE_INTEGER" {} \; \
| xargs gsed -i '1s/^/#include <stdint.h>\n/'
잘 모르겠어서 -and
주는 곳
gsed: can't read /tmp/: No such file or directory
...
나는 commandlinefu의 예를 따랐습니다.여기.
새 명령을 GNU SED 기반 조회에 어떻게 결합합니까?
답변1
나는 다음과 같은 두 가지 작업 find
에 1을 사용합니다.-exec
찾다. -유형 f -exec grep -qFSOME_STRING{} \; -sed 실행'주문하다'{} \;
두 번째 명령은 첫 번째 명령이 다음과 같이 평가되는 경우에만 실행됩니다.진짜즉종료 코드 0
따라서 sed
문제의 파일은 파일에 다음이 포함된 경우에만 처리됩니다.SOME_STRING. 작동 방식을 쉽게 확인할 수 있습니다.
찾다. -유형 f -exec grep -qFSOME_STRING{} \; -인쇄
다음을 포함하는 파일만 나열해야 합니다.SOME_STRING. 물론, 항상 두 개 이상의 표현식을 연결하고 !
(부정)과 같은 연산자를 사용할 수도 있습니다. 예를 들면 다음과 같습니다.
찾다. -유형 f -exec grep -qF이것{} \; -exec grep -qF저것{} \; -인쇄
다음을 포함하는 파일만 나열됩니다.이것하지만 포함하지 않습니다저것.
어쨌든 귀하의 경우에는 다음과 같습니다.
gfind /tmp/ -type f \( -name "*.h" -o -name "*.cpp" \) \
-exec ggrep -qF LARGE_INTEGER {} \; \
-exec gsed -i '1s/^/#include <stdint.h>\n/' {} \;
1
나는 당신이 지원 하거나 선택 xargs
하지 않는다고 가정합니다 . 그렇다면 다음 구성을 사용하십시오.-0
--null
찾다. -유형 f -exec grep -lFZSOME_STRING{} + | xargs -0 gsed -s -i '주문하다'
즉, 귀하의 경우:
gfind /tmp/ -type f \( -name "*.h" -o -name "*.cpp" \) \
-exec ggrep -lFZ LARGE_INTEGER {} + | \
xargs -0 gsed -s -i '1s/^/#include <stdint.h>\n/'
첫 번째 것보다 더 효율적이어야 합니다.
또한 둘 다 모든 유형의 파일 이름에서 작동합니다. 더 빠르기 때문에 grep
( 고정 문자열)을 사용하고 있으므로 -F
정규식을 사용할 계획이라면 제거하십시오.
답변2
출력을 gfind
다음으로 파이프하면 됩니다 xargs
.
gfind /tmp/ -type f \( -name "*.h" -o -name "*.cpp" \) -exec ggrep -l "LARGE_INTEGER" {} + | xargs sed -i '1s/^/#include <stdint.h>\n/'
고정 문자열과 일치하기 때문에 해당 -P
옵션을 제거했습니다 .ggrep
그러나 이 솔루션은 개행 문자가 포함된 파일 이름을 잘 처리하지 못합니다. 더 안전한 접근 방식은 gfind
NULL로 끝나는 파일 이름을 강제로 출력하고 루프에서 출력을 반복하는 것입니다 while
.
#!/bin/bash
gfind /tmp/ -type f \( -name "*.h" -o -name "*.cpp" \) -print0 | while read -d '' -r filepath; do
[ "$(ggrep -l "LARGE_INTEGER" "$filepath")" ] && sed -i '1s/^/#include <stdint.h>\n/' "$filepath"
done
독립 실행형 버전이 마음에 드신다면:
gfind /tmp/ -type f \( -name "*.h" -o -name "*.cpp" \) -print0 | while read -d '' -r filepath; do [ "$(ggrep -l "LARGE_INTEGER" "$filepath")" ] && sed -i '1s/^/#include <stdint.h>\n/' "$filepath"; done