두 개의 텍스트 패턴이 포함된 파일 이름을 일치시키려고 하는데 일치 프로세스에서 대소문자를 무시해야 합니다. 다음 정규 표현식은 작동하지 않습니다.
모든 정규식 및 문자열 작업에서 대/소문자를 무시하도록 awk 변수 'IGNORECASE'를 0이 아닌 값(에서 제안한 대로 info awk
)으로 설정한 다음 두 개의 정규식을 사용하여 모든 파일을 인쇄하는 논리적 "and" 작업을 구축합니다.
$ ls -R | awk 'IGNORECASE = 1;/bingo/ && /number/;'
텍스트 패턴 "bingo" 및 "number"를 일치시키기 위해 미리보기(두 번째 미리보기가 필요하지 않다는 것을 알고 있음)를 사용하기 전에 데이터를 소문자로 변환해 보았습니다. 그러나 awk는 기본적으로 출력해야 하는 출력을 인쇄하지 않습니다.1,2
$ ls -R | awk 'tolower($0) ~ /(?=.*bingo)(?=.*number)/'
awk 또는 regex 구문의 어떤 부분이 잘못되었거나 누락되었으며, 추가 패턴이 같은 줄에 나타나는 경우에만 성공하는 대소문자 독립적 검색을 수행하는 올바른 방법은 무엇입니까?
고쳐 쓰다:
달리기에서
$ ls -R | awk '/bingo/'
파일 이름에 일치하는 문자열 상수 "bingo"가 포함되어 있지 않기 awk
때문에 출력의 각 파일에 있는 줄에서 일치가 수행되는 것처럼 보입니다 . 이 경우 파이프에서 출력을 받을 때(즉, 파이프를 통해 전송)와 동일한 동작을 어떻게 얻을 수 있습니까?ls -R
awk
awk
grep
답변1
첫 번째 스크립트를 작성하세요.
awk 'IGNORECASE = 1;/bingo/ && /number/;'
- 의견에서 지적했듯이 IGNORECASE는 dorks로 제한되며
귀하의 awk 코드는 다음과 같습니다:
awk '(IGNORECASE = 1){print}; (/bingo/ && /number/){print}'
따라서 GNU awk에서는 대소문자를 구분하지 않고 일치를 수행하지만 다른 awk에서는 그렇지 않습니다. 그리고 항상 현재 줄을 인쇄합니다(할당이 참 조건 IGNORECASE=1
으로 평가되기 때문에 1
). 그런 다음 빙고와 번호를 포함하는 모든 줄을 인쇄합니다. 두번째.
두 번째 스크립트를 작성하세요.
awk 'tolower($0) ~ /(?=.*bingo)(?=.*number)/'
그것은 ?=
PCRE 둘러보기입니다. awk는 PCRE가 아닌 ERE를 지원하므로 ERE에서 실제로 무엇을 의미하는지 고려해야 하지만 그것이 무엇이든 원하는 의미는 아닙니다.
귀하의 진술은 다음과 같습니다:
awk는 ls -R 출력에서 각 파일의 행에 대해 일치를 수행하는 것으로 보입니다.
왜 그렇게 생각하는지 모르겠지만, 그렇지 않습니다.
나는 이것이 GNU awk에서 원하는 것이라고 생각합니다:
awk 'BEGIN{IGNORECASE=1}; /bingo/ && /number/'
또는:
awk -v IGNORECASE=1 '/bingo/ && /number/'
어떤 경우든:
awk '{lc=tolower($0)}; (lc ~ /bingo/) && (lc ~ /number/)'
답변2
현재 디렉토리나 문자열이 포함된 디렉토리에서 이름을 찾으려면 bingo
어떤 경우에도 number
through의 출력을 전달하지 말고 다음을 사용하십시오.ls -R
awk
find
find . -iname '*bingo*' -iname '*number*'
이 -iname
조건자는 비표준이지만 일반적으로 구현되며 주어진 와일드카드 패턴에 대해 현재 확인 중인 파일 이름과 대소문자를 구분하지 않고 일치합니다.
파일명을 알고 싶다면오직, 찾은 파일의 전체 경로 이름 대신 다음을 사용하십시오.
find . -iname '*bingo*' -iname '*number*' -exec basename {} \;
GNU를 사용하면 find
다음을 사용할 수 있습니다.
find . -iname '*bingo*' -iname '*number*' -printf '%f\n'
를 사용하는 것보다 더 빠릅니다 basename
.
두 단어의 순서가 " bingo
뒤에 number
" 라는 것을 알고 있는 경우 두 테스트 대신 -iname '*bingo*number*'
with를 사용하세요.find
-iname
찾고 있는 단어의 순서가 이것이라는 것을 알고 있다면 bash
다음을 사용할 수도 있습니다.
shopt -s globstar # enable ** to match across / in pathnames
shopt -s nocaseglob # enable case-insensitive globbing
shopt -s failglob # error when a pattern does not match anything
printf '%s\n' **/*bingo*number*
경로 이름의 파일 이름 부분을 얻으려면:
shopt -s globstar nocaseglob failglob
for name in **/*bingo*number*; do
basename -- "$name"
done
또는 GNU가 있고 basename
일치하고 싶지 않은 경우수천파일 수,
shopt -s globstar nocaseglob failglob
basename -a -- **/*bingo*number*
여기서 -a
각 인수(여러 인수)의 파일 이름 부분을 표시하도록 유틸리티에 지시합니다.
Stéphane은 주석에서 두 하위 문자열의 순서를 무시하려면 bash
확장된 globbing 패턴을 사용할 수 있다고 지적했습니다.
!(!(*bingo*)|!(*number*))
이는 다음을 제외한 모든 이름을 일치시켜 수행됩니다.원하지 않는다두 문자열 중 하나를 포함합니다. 그래서 당신은 얻을 것이다
shopt -s globstar nocaseglob failglob
shopt -s extglob # for extended globbing patterns in bash
for name in **/!(!(*bingo*)|!(*number*)); do
basename -- "$name"
done
관련된: