나는 다음과 같은 것을하려고 노력하고 있습니다.
vi `grep -Rl 'keyword'`
하지만 파일 이름에 공백을 지원하고 싶습니다.
vi "`grep -Rl 'keyword'`"
하다아니요필요한 작업을 수행하면 grep 출력을 \n 을 포함하는 단일 인수로 변환합니다.
나는 노력했다
vi "`grep -Rl 'keyword'`| xargs"
보기에는 좋아졌지만 결과는 여전히 단일 인수입니다(이제 \n 대신 공백이 포함됨).
이를 수행할 수 있는 좋은 방법이 있습니까? Bash는 훌륭하고 POSIX 규격을 준수한다는 점도 장점입니다.
추신.
-R 옵션은 모든 grep 구현에서 작동하지 않으며 bash는 ``
.
답변1
사용 find
:
find . -type f -exec grep -q 'pattern' {} \; -exec vi {} +
이것은 현재 디렉토리 안이나 아래의 모든 일반 파일에서 일치하는 행을 찾습니다 pattern
. 발견된 파일에 대해 vi
시작됩니다.
이러한 파일이 수백 개 있으면 vi
배치 파일이 호출됩니다. -exec vi {} +
파일당 한 번씩 호출되도록 변경되었습니다 -exec vi {} \;
.vi
grep -q
실제로 출력에는 전혀 관심이 없고 grep
종료 상태에만 관심이 있기 때문에 이를 사용합니다 .
이는 유효한 Unix 파일 이름을 허용하며 POSIX와 완전히 호환됩니다(재귀 grep
는 아님).
답변2
어때요?
grep -Rl 'pattern' | xargs -d '\n' vi
-d
이 옵션이 얼마나 POSIXy인지 모르겠습니다 .
GNU 도구가 있는 경우 모든 파일 이름을 허용하는 것이 좋습니다.
grep -Rlz 'pattern' | xargs -0 vi
답변3
Bash에서 일치하는 파일 이름이 너무 많지 않다고 가정하면 $(getconf ARG_MAX)
또 다른 옵션은 globstar 아래의 확장을 반복 **
하고 일치하는 파일 이름의 배열을 만드는 것입니다.
shopt -s globstar
matching_files=()
for entry in **
do
[ -f "$entry" ] || continue
grep -q 'pattern' -- "$entry" && matching_files+=("$entry")
done
vi -- "${matching_files[@]}"
루프는 현재 디렉터리와 그 아래에 숨겨지지 않은 파일 및 디렉터리를 찾습니다. 우리가 수행하는 첫 번째 테스트는 일반 파일이 있는지 확인하는 것입니다. 그렇다면 grep
Quiet/Silent를 실행하여 원하는 모드를 얻습니다. 파일에 패턴이 포함되어 있으면 해당 파일 이름을 match_files 배열에 추가합니다. 마지막으로 vi
배열의 안전하게 확장된 항목 목록을 사용하여 작업합니다.
숨겨진 파일과 디렉터리도 검색하려면 를 설정하세요 shopt -s dotglob
.