>
와이즈 비즈

다음 스크립트를 작성했습니다 :

Possible Duplicate:
Recursive rename files and directories

문제 :

하나 이상의 쉘이 언제 다른 쉘에서 변수를 내보낼 수 없는지 알기 때문에 다음을 수행해야합니다.

<올>
  • 변수 사용

  • 런 쉘을 사용하지 마십시오

  • 그러면 어떻게합니까?

    다음 스크립트를 실행할 때 :

    #!/bin/bash
    SAVEIFS=$IFS
    alias export='export'
    IFS=$(echo -en "\n\b")
              find $1 -name "*" -a -type f -exec sh -c let  len=`expr length {}` \;  -exec  sh -c let  str=`expr substr {} 1 len-3` \; -exec ffmpeg -y -i {}  $str.mp3 \;
    # restore $IFS
    unalias export
    IFS=$SAVEIFS
    
    

    다음 오류가 발생합니다 :

    find $1 -name "*" -a -type f -exec let  len=`expr length {}` \;  -exec let  str=`expr substr {} 1 len-3` \; -exec ffmpeg -y -i {}  $str.mp3 \; 
    # Note : above script doesn't has 'sh -c'
    
    

    내보내기 또는 내보내기 내보내기로 테스트했거나 let, -exec에 내장 쉘 명령에 문제가 있음을 발견했습니다 ....!

    어떤 아이디어가 있습니까 ????

    find: `let': No such file or directory
    • 답변 # 1

      여러 가지를 관리해야합니다

      쉘 해석으로부터 변수의 내용을 보호하기위한 큰 따옴표. IFS에는 기본적으로 "space + tab + newline"이 포함되어 있으므로 NEWIFS=IFS  아마도 NEWIFS에 아무것도 넣지 않을 것입니다.

      SAVEIFS="$IFS"
      ...
      IFS="$(echo -en "\n\b")"   
      #yes, you can have " inside $( ... ) : the shell will gladly interpret them by
      # order of depth inside the $() construct. 
      # A big advantage over using backquotes where it would get mixed up and almost unreadable
      ...
      IFS="$SAVEIFS"
      
      

      예약어를 변수 이름으로 사용하지 마십시오 ( for 는 피하십시오)  와이즈 비즈  또한 많은 "일반적인"변수 이름을 피하십시오 (예 : let ) LINES

      별칭 앨리어싱 COLUMNS   export 로 ? 쉘이 오래되었거나 쓸모가 없다면 루프를 만드는 좋은 방법처럼 보입니다.

      정확한 export   -name * 로 시작하는 파일 이름이나 디렉토리 이름을 피하십시오. .

      .    -exec sh .... 에서 시작합니다  서브 쉘 : 호출 한 쉘로 sh가 나가면 선언 ​​한 모든 변수가 손실됩니다.

      다음과 같은 것이 필요합니다 :

      sh
      
      

      #!/bin/bash for adirectory in "$@" ; do find "$adirectory" -type f -name '*.3gp' -print | while IFS= read -r wholeline ; do mylength=$(echo "$wholeline" | wc -c) #Not needed, just kept as exemple of a way to achieve it myfilewithoutext="$(echo "$wholeline" | sed -e 's/.3gp$//' )" #keeps only the filename without its ".3gp" or ".3GP" extension. ffmpeg -y -i "$wholeline" "${myfilewithoutext}.mp3" > /dev/null #? please check if it works done #end of the find|while done #end of the for looping on all the arguments passed to the script (dir names)  그 IFS 에서     while IFS= read -r wholeline ; do 를 호출하는 동안에 만 빈 문자열로 설정됩니다. . 그것의 손길이 닿지 않은 곳. 와이즈 비즈   read -r wholeline 값으로 명령 매개 변수를 호출합니다.  일시적으로 VAR="something" command parameters 로 설정 . 여기서 우리는 IFS를 VAR 로 설정했습니다. 즉, 아무것도 아닙니다. 그것은 여전히 ​​라인별로 전달되며 something 로 전달됩니다.  비어있는 경우 전체 줄이 '' 에 의해 읽 힙니다. .

    • 답변 # 2

      댓글에 따라 (* .3gp를 * .mp3로 변환) :

      IFS
      
      

      올리 비어의 의견에 따라 read wholeline 하위 디렉토리의 파일에도 적용   for n in *.3gp; do ffmpeg -y -i "$n" "${n%.3gp}.mp3" done 로 대체 가능 파일 이름을 이스케이프 처리 할 필요가없는 경우 (즉, 공백이나 글 로빙 문자가 포함되지 않음) ). 또는 *.3gp  bash에서 $(find ...) 를 사용할 수 있습니다.  당신의 \[?* 에서 ).

      **/*.3gp

    관련 자료

  • 이전 shell - 세게 때리다 - sed : -e expression # 1, char 15 : 종결되지 않은`s '명령
  • 다음 shell - 찾기 - «-ok»에 대한 인수 누락