이것이 계속이다비대화형 쉘을 위한 환경 변수로 배열 저장 - Think Tank 101 - CC 저작권 기반 Q&A 공유 플랫폼.선행은 이루기가 어렵다, 또 다른 질문을 드리겠습니다.
특정 정규식 일치가 포함된 모든 Markdown 파일을 찾은 다음 파일의 출력(가장 많은 검색어 포함)을 오름차순으로 정렬하고 싶습니다.
GREP(){
export Regex
xargs -0 -I "{}" bash -c 'grep "${GrepOption[@]}" --only-matching --with-filename --extended-regexp --regexp="${Regex}" "${1}" 2> /dev/null | wc -l | xargs printf "${1}:%s\n" ' _ "{}" \;
}
find . -name "*.md" -print0 | GREP | grep -v ':0$' | sort -n -r -k2 -t:
사용자는 "${Regex}"를 입력합니다. 여기서 GrepOptions는 사용자 입력에 따른 옵션 배열입니다. 예를 들어 GrepOptions는 GrepOptions=("--ignore-case")
grep 옵션의 다른 배열일 수 있습니다.
GrepOptions
하지만 서브쉘 환경에서는 어레이를 사용할 수 없습니다 .
어떤 제안이 있으십니까?
답변1
문제는 GrepOptions
코드에서 배열을 환경 변수로 사용하려는 것입니다. 배열을 내보낼 수 없기 때문에 이 작업을 수행할 수 없습니다.
bash -c
대신 를 실행하려면 경로 이름과 함께 옵션을 스크립트에 전달해야 합니다 grep
.
아래에서는 한 단계 더 나아가 정규식과 여러 개의 발견된 경로 이름을 전달 -exec
했으며 .find
xargs
경로 이름에서 사용자 옵션을 구분하기 위해 --
스크립트 호출에 사용합니다 .bash -c
find . -name '*.md' -type f -exec bash -c '
re=$1; shift
while [[ $1 != "--" ]]; do
opts+=( "$1" )
shift
done; shift
for pathname do
printf "%s:" "$pathname"
grep -o -E -e "$re" "${opts[@]}" -- "$pathname" |
wc -l | tr -d "[:blank:]"
done | grep -v ":0$"' bash "$user_regex" "${user_options[@]}" -- {} + |
sort -t : -k2,2n
.md
그러면 현재 디렉터리나 다음 디렉터리로 끝나는 파일 이름을 가진 모든 일반 파일을 찾습니다. 이러한 파일 배치의 경우 bash
사용자 제공 확장 정규식( $user_regex
), 일부 사용자 제공 명령 옵션 grep
( $user_options
, 배열) 및 경로 이름 배치를 사용하는 스크립트가 실행됩니다.
인라인 스크립트는 정규식과 사용자 옵션을 선택한 다음 찾은 파일을 반복하면서 grep
각 파일을 실행하고 반환된 줄 수를 계산합니다.
각 파일 경로 이름은 끝에서 한 문자 뒤에 이 숫자를 출력합니다 :
.
일치하는 항목이 없음을 나타내는 출력은 제거되고 전체 결과의 순위가 매겨집니다.
이 코드는 경로 이름을 처리하는 방식으로 인해 줄 바꿈이나 콜론이 포함된 경로 이름을 지원하지 않습니다. 또한 배열 user_options
에는 개별 이중 대시가 포함될 수 없습니다.
답변2
bash -c 'grep ${grepOptions+$grepOptions} ....'
- grepOptions는 공백으로 구분된 grep 옵션을 포함하는 쉘 변수입니다.
- ${var+alternative} 네이키드를 사용하세요. 옵션이 비어 있지 않으면 사용하세요. 그렇지 않으면 따옴표 없이 e를 비워두세요. 그러면 구문 분석이 중단됩니다.
- 이는 쉘 변수를 내보낼 수 있음을 의미합니다.