sed
백슬래시가 있는 경로를 슬래시가 있는 동일한 경로로 변환하는 데 사용하고 싶은 것 :
\\path\to\file\
예를 들어 파이프라인을 통과 하고 싶습니다./path/to/file
전혀다음 명령이 작동하지만 이유를 모르겠습니다.
첫 시도:
> echo '\\path\to\file\' | sed 's/\\/\//g'
/path o
ile/
두 번째 시도:
echo \\path\to\file\ | sed 's/\\/\//g'
/pathtofile
세 번째 시도:
echo "\\path\to\file\" | sed 's/\\/\//g'
dbquote>
파이프하려고 하면 다음과 같은 동작이 발생합니다. | tr '\' '/'
나는 정답을 찾고 있으며 가능하다면 위의 시도 중 어느 것도 작동하지 않는 이유에 대한 설명을 찾고 있습니다. 이것이 중요한지 확실하지 않지만 모든 것이 있습니다.zsh 4.2.6 (x86_64-redhat-linux-gnu)
감사해요!
답변1
file='\\path\to\file\'
printf '%s\n' "$file" | tr -s '\\' /
지쉬어:
setopt extendedglob
print -r -- ${file//\\##/\/}
답변2
를 사용하지 마십시오 echo
. 문제 echo
는 버전이 너무 많아서 각각 백슬래시를 약간 다르게 처리한다는 것입니다. 귀하는 분명히 원래 문자열의 백슬래시를 해석하고 있습니다. 방금 이걸 했다면
# first attempt
echo '\\path\to\file\'
당신이 볼 수 있을지 의심 스럽습니다
\path o
ile\
마찬가지로 다른 모든 시도에서 문제는 파이프의 두 번째 부분( 또는 )이 아니라 사용법 echo
과 쉘 인용과 백슬래시 간의 상호 작용 입니다 .echo
sed
tr
해결책은 printf
이것을 사용하는 것입니다. 동작이 더 일관되고 이식 가능합니다.POSIX에 의해 지정됨.
printf '\\\\path\\to\\file\\\n'
당신을 얻을
\\path\to\file\
답변3
POSIX를 사용하여 이 작업을 수행할 수 있습니다 heredoc
.
% sed -e 's@\\@/@g' -e 's@\(.\):\(.*\)@/drive/\1\2@' <<'_EOF_'
> c:\some\stupid\windows\place
> _EOF_
/drive/c/some/stupid/windows/place
내 대답함수에서 해석되지 않은 실제 쉘 인수를 얻는 방법이 있습니까?read
필요한 경우 명령 대체를 통해 이를 쉘 변수로 동적으로 변환하고 이를 쉘 함수에 인수로 전달하는 방법을 포함하여 이에 대해 더 자세히 설명합니다 .
내 대답에ssh $host $FOO 및 ssh $host "sudo su user -c $FOO" 유형 구성에서 참조됩니다.나는 이미 잘 대답된 질문에 대해 잠재적으로 다른, 그리고 더 직접적인 접근 방식을 제안합니다.
편집하다:죄송합니다. 처음에는 귀하의 요청을 무시했습니다."[질문에 표시된 백슬래시를 인용] 위의 [귀하의] 시도 중 어느 것도 작동하지 않는 이유를 설명하십시오."
답을 이해하는 요령은 그 자체로는 그리 신비롭지는 않지만 불행히도 다소 직관적이지 않습니다. 우리가 일반적으로 직면하는 가장 큰 장애물, 적어도 내가 직면한 가장 큰 장애물은 이것이 shell
컴퓨터와의 기본 인터페이스라는 것입니다. 그래서 가끔은 그것이 단지 프로그램일 뿐이라는 사실을 기억하기 어려울 때가 있습니다. 그것은 다른 앱과 다를 바 없습니다.
shell
" "라고 부르는 대신 이름을 약간 변경하면 더 쉽게 볼 수 있습니다 command interpreter
.(그러나 shell
단어가 전문 용어의 의미를 덜 상속하는 경향이 있고 그 의미도 마찬가지로 좋을 수 있습니다.기본 의미좀 더 눈에 띕니다).
shell
나는 그것이 내 것이 되었을 때 내가 할 수 있는 일에 통제력이 덜하다고 생각하는 것이 더 쉽고 더 정확하다는 것을 알았습니다 interpreter
. 이런 식으로 나는 그것이 나에게만 설명하는 것이 아니라 그 목적과 본질에 맞게 기회가 주어지면 이해하는 모든 대화를 중재하려고 노력한다는 것을 기억하기가 더 쉽습니다 shell
. 다른 응용 프로그램에 대해 설명하십시오. 필요 여부에 관계없이 프로그램에 의해 전달되는 데이터입니다.
내 의도는 command interpreter
기본적으로 전달된 모든 정보를 자체 언어로 자연스럽게 해석하지만 해당 언어 자체가 반드시 다른 응용 프로그램의 언어보다 더 정확하지는 않습니다. 물론 다른 응용 프로그램의 경우 좋은 언어를 구사하면 장점이 있고 command interpreter
직접 설명하는 수고를 덜어줄 수 있지만 세상의 모든 컴퓨터 프로그램이기 때문에 시도해 볼 권리도 동일합니다. 끝.
명령을 해석하는 데 옳고 그른 단 하나의 방법이 없으므로 자매 응용 프로그램의 상황이 복잡해집니다. 유닉스에 관한 한 정정에 가장 가까운 것(그래서 전혀 없다고 할 수 있습니다)아마도 POSIX 표준일 수도 있지만 확실히 해석의 여지가 있습니다.(이것은 말하기에 재미있고 아마도 내 요점을 설명할 수 있기를 바랍니다.). 그 결과 인간 아날로그 언어의 여러 방언과 유사한 디지털 언어가 탄생했습니다.(역시 매우 흥미롭다).
(위의 내용 중 대부분은 입문서일 뿐이며 다음 내용을 완전히 이해하는 데는 다소 불필요할 수 있지만 도움이 되기를 바랍니다.)
명령을 전달하면 명령을 shell
전달하기 전에 명령을 어떤 순서로 해석하도록 프로그래밍된 일련의 규칙을 반복합니다.우리 명령에 대한 해석설명된 바와 같이, 우리는 그렇게 되기를 바랍니다. 어떤 규칙과 해당 규칙이 고려되는 순서에 영향을 미치는 주요 수단(물론 명령 자체는 제외)shell quotes
발견한 대로 일반적으로 \
백슬래시 문자를 포함하는 다양한 유형입니다 .
다른 애플리케이션도 자신만의 해석 규칙 세트를 적용할 수 있는 이유와 권리가 거의 동일하지만 첫 번째 실행 전에는 기회가 거의 없으므로 shell
일반적으로 동일한 규칙을 채택하면 해당 규칙이 모방됩니다. shell
이는 메커니즘을 참조할 때 복잡해질 수 있습니다. shell
, 이는 우리에게 부담을 주므로(헤헤)도착하다 \'"quote our quotes"\'
. 이러한 복잡성은 대상 응용 프로그램과 대상 응용 프로그램 간의 참조 구문에 작은 차이만 있을 때 실망스러울 정도로 확대될 수 shell
있으며 번역에 사용하기 위한 번거로운 지침으로 문제를 간접적으로 해결해야 하는 경우 프로세스에서 아무것도 손실되지 않습니다.
위의 코드 블록에서 설명했듯이 이 상황을 처리할 때 제가 선호하는 방법은 shell
붙여넣을 위치를 직접 지정하는 것입니다. 말하자면 모든 것을 무시해야 합니다. <<'HERE'
제 생각에는 이 상황을 처리할 수 있을 것 같습니다. 정말 감사합니다. 대화에 \nHERE\n
다시 주의를 기울여야 할 때를 알려드리겠습니다 .
답변4
에서 bash
첫 번째 시도는 매력적이었습니다. echo
실행 중인 항목과 버전에 따라 다릅니다 . 예를 들어 echo
bash 내장 명령은 /bin/echo
또는 를 재정의합니다 /usr/bin/echo
. 허용되는 옵션을 기본 옵션과 확인 man bash
하고 비교하세요.info zsh
당신이 정말로 원하는 것은 echo -E
이스케이프 시퀀스 해석을 강제로 비활성화하는 것입니다. 이는 기본값이지만 bash
분명히 그렇지 않습니다 zsh
. 또한 이 특정 내장 함수를 비활성화하거나(저는 이 함수를 사용하지 않아서 zsh
어떻게 하는지 모르겠습니다) 이를 처리하는 가장 일반적인 방법을 사용할 수도 있습니다. 즉, echo
as를 명시적으로 호출하는 것입니다 /bin/echo
.
편집: 물론 작은 따옴표가 필요합니다. 그렇지 않으면 쉘은 echo
기회가 생기기 전에 이스케이프 시퀀스를 해석합니다.