for 루프에서 정규식 사용

for 루프에서 정규식 사용

파일 디렉터리를 반복하여 정규식과 일치시킨 다음 적절한 문자를 바꾸고 싶습니다.

#somefile.txt
%somefile.txt
>somefile.txt

# arr=(\% \> \#) ;for f in *; do echo -- "$f" "${f//${arr[@]}/}"; done

에코해야 합니다:

#somefile.txt -- somefile.txt
%somefile.txt -- somefile.txt
>somefile.txt -- somefile.txt

대신 나는 다음을 얻습니다.

#somefile.txt -- #somefile.txt
%somefile.txt -- %somefile.txt
>somefile.txt -- >somefile.txt

이것은 어떤 변화로도 이어지지 않습니다. nada, zilch.

arr(\%)단일 문자를 사용하면 배열이 작동하므로 전체 목적이 무산됩니다.

#somefile.txt -- #somefile.txt
%somefile.txt -- somefile.txt
>somefile.txt -- >somefile.txt

답변1

여기서 핵심 문제는 ${PARAMETER/PATTERN/STRING}확장이 PATTERN배열을 허용하지 않는다는 것입니다 PARAMETER. 따라서 ${arr[@]}확장은 "% > #".

몇 개의 파일을 추가하면 다음과 같은 효과를 볼 수 있습니다.

# touch "% > #somefile.txt"
# touch "%>#somefile.txt"

명령의 결과는 다음과 같습니다.

#somefile.txt -- #somefile.txt
%somefile.txt -- %somefile.txt
>somefile.txt -- >somefile.txt
%>#somefile.txt -- %>#somefile.txt
% > #somefile.txt -- somefile.txt

마지막 줄은 무슨 일이 일어나고 있는지 정확하게 보여주기를 바랍니다.

또 다른 사람은 파이핑을 $f통해 sed거기에서 마법을 수행할 것을 제안했습니다. 이는 더 복잡한 변환을 허용하므로 좋은 옵션이 될 것이지만, 선행 문자만 제거하고 싶다고 가정하면 bash를 사용하십시오.${PARAMETER#WORD} 매개변수 확장충분할 것입니다:

# gpat=" ;for f in *; do echo -- "$f" "${f#$gpat}"; done

나 자신의 경우 이 줄의 결과는 다음과 같습니다.

>somefile.txt -- somefile.txt
#somefile.txt -- somefile.txt
%somefile.txt -- somefile.txt
%>#somefile.txt -- >#somefile.txt
% > #somefile.txt --  > #somefile.txt

$gpat저는 이 패턴을 "a"라고 부르겠습니다 .Bash 와일드카드 패턴. 그것은아니요정규식.

욕심 이 ${PAR#WORD}없으며 가능한 가장 짧은 패턴과 일치합니다. ${PAR##WORD}가능한 가장 긴 패턴과 일치합니다. 그러나 의 경우 gpat="[%>#]"문자 하나만 일치합니다.

# gpat="[%>#]" ;for f in *; do echo "$f" -- "${f##$gpat}"; done

%somefile.txt -- somefile.txt
>somefile.txt -- somefile.txt
#somefile.txt -- somefile.txt
%>#somefile.txt -- >#somefile.txt
% > #somefile.txt --  > #somefile.txt

extglob쉘 옵션을 설정 하면 (확인 shopt extglob, 설정 shopt -s extglob, 설정 해제 shopt -u extglob- 합당한 옵션이 있으면 설정되었을 가능성이 높음 bashrc) 확장된 글로빙 모드를 사용할 수 있습니다.

# gpat="+([%>#])" ;for f in *; do echo "$f" -- "${f##${gpat}}"; done

%somefile.txt -- somefile.txt
>somefile.txt -- somefile.txt
#somefile.txt -- somefile.txt
%>#somefile.txt -- somefile.txt
% > #somefile.txt --  > #somefile.txt

그러나 위의 모든 예에서 % 뒤의 공백이 패턴에 의해 캡처되지 않기 때문에 발생한다는 점은 주목할 가치가 있습니다 "% > #somefile.txt"." > #somefile.txt"

물론 ${PARAMETER/PATTERN/STRING}(및 //유사)도 와일드카드 패턴을 허용하지만 이 단어를 입력할 때 이것을 (문자 그대로) 깨달았고 이를 반영하기 위해 위의 내용을 검토하기에는 너무 게으른 편입니다. 어쨌든, PAR/PAT/문자열 중간에 있는 문자를 제거하는 데만 사용한다는 점을 제외하면 완전히 동일하게 작동합니다 .

답변2

이것은 나에게 효과적인 것 같습니다 ...

$ ls
#somefile.txt  %somefile.txt  >somefile.txt

$ for f in *; do j=`echo $f | sed -e's/[\%\#\>]//g'`; echo "$f -- $j"; done
#somefile.txt -- somefile.txt
%somefile.txt -- somefile.txt
>somefile.txt -- somefile.txt

관련 정보