변수 앞뒤의 하위 문자열 삭제

변수 앞뒤의 하위 문자열 삭제

변수 앞 부분 문자열을 제거할 수 있다는 것을 알고 있습니다.

X=foobarbaz
echo ${X#foo}       # barbaz

...그리고 변수 뒤에서:

echo ${X%baz}       # foobar

이 둘을 어떻게 결합하나요? 나는 시도했다:

echo ${{X#foo}%baz}    # "bad substitution"
echo ${${X#foo}%baz}   # "bad substitution"
echo ${X#foo%baz}      # foobarbaz

나는 아니에요생각하다다음 과 같이 중간 변수를 사용할 수 있습니다 find -exec.

find ./Source -name '*.src' \
    -exec bash -c 'myconvert -i "{}" -o "./Dest/${0#./Source/%.src}.dst"' {} \;

답변1

나는 이것이 가능하다고 생각하지 않습니다(그러나 틀렸다는 것이 증명되기를 바랍니다). 그러나 중간 변수를 사용할 수 있습니다. 다른 인스턴스와 마찬가지로 러너는 단지 bash 인스턴스 bash -c입니다 .-exec

$ find . -type f
./foobarbaz
$ find . -type f -exec bash -c 'v=${0#./foo}; echo ${v%baz}'  {} \;
bar

따라서 이것이 왜 작동하지 않는지 알 수 없습니다(귀하가 올바르게 수행하려는 작업을 이해한다면).

find ./Source -name '*.src' \
     -exec bash -c 'v=${0%.src}; \ 
        myconvert -i "{}" -o "./Dest/${v#./Source/}.dst"' {} \;

답변2

일반적인 접근 방식은 다음 두 단계로 수행하는 것입니다.

x=foobarbaz
y=${x#foo}       # barbaz
z=${y%baz}       # bar

이는 "매개변수 확장"이므로 대체를 수행하려면 "매개변수"(변수)가 필요합니다. 즉, y와 z가 필요합니다. 동일한 변수이더라도 다음과 같습니다.

x=foobarbaz
x=${x#foo}       # barbaz
x=${x%baz}       # bar

find ./Source/ -name '*.src' -exec \
    bash -c '
        x=${1#./Source/}
        myconvert -i "$1" -o "./Dest/${x%.src}.dst"
    ' shname {} \;

shname매개변수는 어디에 있고 $0, 다음 매개변수는 bash 호출의 매개변수 {}입니다 .$1


cd ./Source더 쉬운 옵션은 나중에 해당 부분을 삭제하지 않도록 처음에 수행하는 것입니다. 그것은 다음과 같습니다:

cd ./Source                 ### Maybe test that it exist before cd to it.
shopt -s extglob nullglob   ### Make sure that correct options are set.

for f in *.src **/*.src; do
    echo \
    myconvert -i "$f" -o "./Dest/${f%.src}.dst"
done

원하는 대로 작동한다고 확신하면 에코를 주석 처리하세요.

답변3

나는 항상 단계별로 수행합니다.

X=foobarbaz; X="${X#foo}"; X="${X%baz}"

답변4

이것이 아직 제안되지 않은 것에 놀랐습니다. 하지만 Bash하위 문자열 확장당신을 위해 그것을 할 것입니다. 접두사와 접미사의 길이를 알고 있는 경우 간단히 다음을 수행할 수 있습니다.

X=foobarbaz
echo ${X:3:-3}
# output: bar

접두사와 접미사가 변수인 경우 POSIX 표준을 사용해야 합니다.문자열 길이 확장오프셋 가져오기:

X=foobarbaz
prefix=fo
suffix=az
echo ${X:${#prefix}:-${#suffix}}
# output: obarb

관련 정보