슬래시가 포함된 문자열을 sed에 전달하여 값을 추출해야 하지만 그렇게 하려고 하면 해당 문자열을 디렉터리/파일로 취급하고 "해당 디렉터리 또는 파일이 없습니다"라는 오류가 발생합니다. 나는 이것이 경로로 읽고 의도한 효과가 아닐 때 파일을 찾으려고 시도하기 때문이라고 가정합니다. 예:
my_value="my/value"
operand="$($my_value | sed -n -e 's/^\(.*\)\/.*/\1/p')"
# Expected echo $operand : my
참고: 저는 bash 스크립팅을 처음 접했기 때문에 이것이 잘못된 접근 방식일 수 있습니다.
답변1
원하는 출력이 echo $operand
이면 my
다음 한 가지 누락을 제외하고는 구문이 괜찮습니다.
operand="$(echo $my_value | sed -n -e 's/^\(.*\)\/.*/\1/p')"
해당 값을 stdout으로 보내 작업을 수행하려면 변수를 echo
사용해야 합니다 . 변수 값인 파일이나 디렉터리가 실제로 호출되지 않기 때문에 오류가 발생합니다 .my_value
sed
my/value
위 operand
변수에 대한 명령 대체 포함은 사용 시 출력됩니다 echo
.my
echo $operand
또 다른 방법은 다음과 같습니다.
operand="$(printf '%s\n' "$my_value" | sed -n -e 's/^\(.*\)\/.*/\1/p')"
printf
이는 포함된 다른 문자열에 대해 echo가 작동하지 않도록 하는 더 나은 경우 중 하나입니다 . 이 경우에는 발생하지 않지만 다른 경우에는 발생할 수 있습니다.
답변2
빌드하는 파이프라인은 한 명령의 출력을 다른 명령의 입력으로 사용합니다. 이름이 지정된 파일을 실행하려고 하는데 my/value
해당 파일이 없다는 메시지가 나타날 수 있습니다.
원하는 것을 수행하는 방법에는 여러 가지가 있습니다.
이 방법은 여전히 파이프를 사용하며 아마도 가장 이식성이 뛰어날 것입니다.
operand="$(echo "$my_value" | sed -n -e 's/^\(.*\)\/.*/\1/p')"
쉘이 이를 지원하는 경우 대안은 다음과 같습니다(적어도 bash에서는 작동해야 함).
operand="$(sed -n -e 's/^\(.*\)\/.*/\1/p' <<< "$my_value")"
후자의 접근 방식은 변수 값을 표시하기 위해 추가 프로시저를 호출하지 않기 때문에 약간 더 선호됩니다.
두 경우 모두 변수 내용을 큰따옴표로 보호하는 것이 가장 좋습니다.
답변3
$my_value
다른 사람들이 지적했듯이 명령 대체에서 명령으로 값을 실행 하려고합니다 .
/
문자열의 첫 번째 항목 이후의 모든 항목을 제거하려면 명령 대체를 사용하십시오.
my_value="this/is/my/value"
operand=${my_value%%/*}
printf '%s\n' "$operand" # will output the string "this"
매개변수 확장으로 ${my_value%%/*}
인해 일치하는 가장 긴 접미사 문자열이 /*
value 에서 제거됩니다 $my_value
. 이것은표준 매개변수 확장그리고 쉘은 호출보다 훨씬 빠르게 실행됩니다 sed
.
또한, in의 $my_value
값 이경로명, sed
기술적으로 개행 문자가 포함될 수 있으므로 조작하는 것은 위험합니다. 개행 문자가 포함된 경로 이름을 처리하려면 쉘에서 매개변수 확장을 사용하십시오.