MSG
내 경로에서 제외 하고 괄호를 사용하여 쉘 매개변수 확장을 사용하고 싶습니다 PDF
.DOC
MSG
괄호 사이에 넣으면 M
삭제되지 않고 삭제만 됩니다 MSG
. 인터넷을 둘러보고 설명서를 읽었지만 여전히 이 작업을 올바르게 수행하는 방법을 이해할 수 없습니다. 어쩌면 내가 검색하기에 적합한 키워드를 모르는 것일 수도 있습니다.
내 코드는 MSG만 제거합니다.
find "${INPUTPATH}" -mindepth 2 -maxdepth 2 -type d -print0 | while IFS= read -r -d '' file; do
echo "${file}"
casenumber="${file#${INPUTPATH}/[MSG]}"
echo "${casenumber}"
done
입력하다:
/home/user/output/test/PDF/2218-0
/home/user/output/test/PDF/2218-0
/home/user/output/test/DOC/2218-0
/home/user/output/test/DOC/2218-0
/home/user/output/test/MSG/2226-4
/home/user/output/test/MSG/2226-4
/home/user/output/test/MSG/2222 -2
/home/user/output/test/MSG/2222 -2
/home/user/output/test/MSG/2218-0
/home/user/output/test/MSG/2218-0
현재 MSG를 제거하는 출력:
/home/user/output/test/PDF/2218-0
/home/user/output/test/PDF/2218-0
/home/user/output/test/DOC/2218-0
/home/user/output/test/DOC/2218-0
/home/user/output/test/MSG/2226-4
SG/2226-4
/home/user/output/test/MSG/2222 -2
SG/2222 -2
/home/user/output/test/MSG/2218-0
SG/2218-0
예상 출력:
/home/user/output/test/PDF/2218-0
/home/user/output/test/PDF/2218-0
/home/user/output/test/DOC/2218-0
/home/user/output/test/DOC/2218-0
/home/user/output/test/MSG/2226-4
/2226-4
/home/user/output/test/MSG/2222 -2
/2222 -2
/home/user/output/test/MSG/2218-0
/2218-0
실제로 MSG, PDF, DOC를 이런 식으로 삭제하고 싶습니다.
find "${INPUTPATH}" -mindepth 2 -maxdepth 2 -type d -print0 | while IFS= read -r -d '' file; do
echo "${file}"
casenumber="${file#${INPUTPATH}/[MSG][PDF][DOC]/}"
echo "${casenumber}"
done
위 코드가 작동하지 않는 이유를 이해합니다. 하지만 이 작업을 수행하려면 먼저 MSG를 해결해야 합니다.
최종 예상 출력:
/home/user/output/test/PDF/2218-0
2218-0
/home/user/output/test/DOC/2218-0
2218-0
/home/user/output/test/MSG/2226-4
2226-4
/home/user/output/test/MSG/2222 -2
2222 -2
/home/user/output/test/MSG/2218-0
2218-0
답변1
[MSG]
전역 패턴은 하나의 문자 M
또는 S
와 일치합니다 G
. MSG
, DOC
또는 를 일치시키려면 in 또는 in ksh를 PDF
사용할 수 있습니다 . bash는 zsh glob 연산자를 지원하지 않지만 after를 포함한 ksh 연산자의 하위 집합을 지원하므로 bash에서는 다음과 같습니다.(MSG|DOC|PDF)
zsh
@(MSG|DOC|PDF)
shopt -s extglob
shopt -s extglob
casenumber=${file#"${INPUTPATH}"/@(MSG|DOC|PDF)}
에 할당되어 내용과 일치하는 가장 짧은 선행 부분을 제거하고 casenumber
(말 그대로 zsh와 달리 ksh/bash에서 필요한 주변 따옴표 덕분에) , 또는 가 뒤따릅니다.$file
$INPUTPATH
/
MSG
DOC
PDF
shopt -s extglob
ksh에서는 bash에만 해당되고 ksh에서는 필요하지 않은 항목을 생략하세요 . zsh에서:
casenumber=${file#$INPUTPATH/(MSG|DOC|PDF)}
답변2
실제로 와일드카드는 아니지만...
=~
확장된 테스트 대괄호 내에서 사용하면 최신 버전의 Bash는 RegEx 연산자를 사용하여 정규식 기반 일치를 수행할 수 있습니다 [[ ... ]]
. 캡처 그룹을 수행할 수 있으며 0번째 인덱스가 하나의 인덱스 아래 전체 일치를 참조하는 (...)
내장 배열이 있습니다. 첫 번째 캡처링 그룹 일치를 참조하고, 다음은 두 번째 캡처링 그룹 일치를 참조하는 식입니다.BASH_REMATCH
${BASH_REMATCH[0]}
${BASH_REMATCH[1]}
${BASH_REMATCH[2]}
따라서 다음과 같이 할 수 있습니다.
$ printf '%s\0' "/home/user/output/test/PDF/2218-0" "/home/user/output/test/DOC/2218-0" "/home/user/output/test/MSG/2226-4" |
while IFS= read -r -d '' file; do
[[ "$file" =~ .*(DOC|MSG|PDF)(.*) ]] && printf '%s\n' "$file" "${BASH_REMATCH[2]}"
done
/home/user/output/test/PDF/2218-0
/2218-0
/home/user/output/test/DOC/2218-0
/2218-0
/home/user/output/test/MSG/2226-4
/2226-4
답변3
정확한 질문에 대답하는 것이 아니라 이 특정 사례에 대한 몇 가지 참고 사항입니다.
현재 위치에 있다는 점을 고려하면 find "${INPUTPATH}" -mindepth 2 -maxdepth 2
생성된 모든 경로에는 초기 경로 뒤에 슬래시가 하나만 있어야 하므로 $INPUTPATH
거기에 있는 특정 세 글자 문자열을 무시하고 다음 문자열 앞의 모든 항목을 제거하면 됩니다 /
.
casenumber=${file#"${INPUTPATH}"/*/}
아니면 마지막 슬래시이므로 그냥 제거하세요.모든 것끝까지 /
:
casenumber="${file##*/}"
여기서 두 배로 한다는 것은 #
가장 긴 경기를 치르는 것을 의미합니다.
또한 이전에 실행한 경우 $INPUTPATH
출력에서 해당 부분을 제거할 수 있습니다(다음으로 교체하기만 하면 됨) ..
cd
find
(cd -P -- "${INPUTPATH}" && find . -mindepth 2 -maxdepth 2 -type d -print0) |
while IFS= read -r -d '' file; do
echo "${file}"
casenumber="${file#./*/}"
echo "${casenumber}"
done