2016-11-08 4 views
3

그래서 파일 이름에서 특수 문자를 제거하고 공백으로 바꿉니다. 나는 거기에 포함 된 단일 백 슬래시가있는 파일을 제외하고는 모두 작업하고 있습니다. 이 파일은 OS X이되는 NEW_NAME 결과tr로 백 슬래시 제거

old_name="testing\this\folder" 
new_name=$(echo $old_name | tr '<>:\\#%|?*' ' '); 

에 Finder에서 생성 참고 가 어떻게 바로 앞의 문자를 백 슬래시를 제거 할 수 없습니다 "hisolder는 테스트?" 더 shell parameter expansion에서 bash 설명서를 참조하십시오 들어

$ old_name="testing\this\folder" 
$ new_name=${old_name//[<>:\\#%|?*]/ } 
$ echo $new_name 
testing this folder 

:

+1

_special characters_를 어떻게 정의 하느냐에 따라 'tr -d'[: punct :] '' –

답변

3

"테스트 hisolder"

\t\f 실제로 대체되기 때문에이 캐릭터는, echo -e "testing\this\folder"의 결과처럼 보인다 표 및 양식 공급 제어 문자.

은 아마 당신은 alias echo='echo -e' 같은 별칭을 가지고, 아니면 쉘의 버전에 echo의 구현은 백 슬래시 이스케이프 해석 :

POSIX는 옵션에 대한 지원을 요구하고 말한다하지의 행동 STRING에 백 슬래시가 있거나 첫 번째 인수가 '-n'이면 'echo'는 구현 정의입니다. 이동식 프로그램은 후행 줄 바꿈을 생략하거나 제어 문자 또는 백 슬래시를 출력해야 할 경우 'printf'명령을 사용할 수 있습니다.

합니다 (정보 페이지에서)

그래서 당신은 새로운 소프트웨어에 printf 대신 echo을 사용해야합니다. 특히 echo $old_nameprintf %s "$old_name"으로 대체해야합니다.

예를 들어, this discussion에 대한 설명이 있습니다.

제안 @ mklement0으로 printf

에 대한 필요, 당신은 Bash here string에 의해 파이프를 피할 수 없다 :

tr '<>:\\#%|?*' ' ' <<<"$old_name" 
2

은 강타, 당신은 매개 변수 확장을 사용할 수 있습니다.

-1

테스트 사례에 \의 적절한 이스케이프가 누락되어 있다고 생각합니다. 따라서 문자열에 포함 된 백 슬래시의 경우를 실제로 테스트하지는 않았습니다.

은 나를 위해 일한 :

old_name='testing\\this\\folder' 
new_name=$(echo $old_name | tr '<>:\\#%|?*' ' '); 
echo $new_name 
# testing this folder 
이되는 NEW_NAME 결과
+0

과 같은 것을 사용할 수 있습니다. 기본 옵션과 함께 Bash (질문의 태그 방식) 내장 된 'echo'를 사용하면 두 개의 백 슬래시가 보존되므로 결과 문자열에는 단어 사이에 _2_ 공백이 생깁니다. (반대로, OP의 코드는 그대로 작동해야합니다.) 그 외에도'$ old_name'은 큰 따옴표로 묶어야합니다. 이스케이프는'xpg_echo' 옵션이 (암시 적으로 또는 명시 적으로) 켜져있는 경우에만 작동하지만 더 나은 해결책은'printf' 또는 here-string을 사용하는 것입니다. – mklement0

2

Ruslan's excellent answer이 명령은 및 제공을 위해 작동하지 않을 수 이유를 설명 견고하고 휴대 가능한 솔루션.

TL은, 박사는 :

  • 당신은 아마 (맥 OS에 sh가 변장 배쉬 경우에도) sh보다는 bash으로 코드를 실행하거나 쉘 옵션 xpg_echo 명시 적으로 설정했다.
  • 이식성을 위해 echo 대신 printf을 사용하십시오.

기본 옵션 배쉬에서

하고 echo 내장을 사용하여 명령은 그대로 작동합니다 (제외 당신해야 따옴표 견고성 $old_name), 기본적으로 echo는 않기 때문에 하지 피연산자에 \t과 같은 이스케이프 시퀀스를 확장합니다. 그러나

, 강타의 echo 제어 문자 이스케이프 시퀀스 확장 할 수있다 : 당신이 sh로 또는 --posix 옵션으로 배쉬를 실행하는 경우, 암시 적으로
  • shopt -s xpg_echo을 실행하여, 명시 적으로

    • 을 (이 , 다른 옵션 및 동작 변경 사항 중 xpg_echo)

    따라서 예를 들어, shebang 줄 #!/bin/sh으로 스크립트에서 코드를 실행하면 문제가 발생할 수 있습니다. 그러나

    , 당신이 휴대용 스크립트를 작성하는 경우, 즉, sh을 대상으로하는 경우, 다음 echo이 동작은 껍질과 플랫폼에서 차이가 바로 그 이유 때문에 모두 피해야한다 - 루슬란의 printf 솔루션을 참조하십시오. 여담으로


    는 명시 적으로 당신의 결과에서 허용 된 문자 만 진술하고 -C 옵션을 사용하여 다른 제외 :

    아마 당신 tr 명령에보다 강력한 방법은 화이트리스트 방법입니다
    old_name='testing\this\folder' 
    new_name=$(printf '%s' "$old_name" | tr -C '[:alnum:]_-' ' ') 
    

    그런 식으로 문자, 숫자, _ 또는 -이 아닌 문자는 공백으로 바뀝니다.

  • +0

    철저한 설명 주셔서 감사합니다. – rndy