cut / awk 대신 bash 변수 대체 사용

분리 계를 기반으로 변수를 추출하기 위해 bash 변수 대체를 사용할 수 있습니까? 파일 이름 (이 경우 foo)의 즉각적인 디렉토리 이름을 가져 오려고합니다.

$ filename=./foo/bar/baz.xml 

echo $filename | cut -d "/" -f 2 

또는

echo $filename | awk -F "/" "{print $2}" 

같은 것을 할 수 있다는 것을 알고 있습니다. ” 여러 파일 이름에 대해 awk / cut를 포크하는 속도가 느려집니다.

다양한 솔루션에 대해 약간의 프로파일 링을 수행했습니다. , 내 실제 파일 사용 :

echo | 컷 :

real 2m56.805s user 0m37.009s sys 1m26.067s 

echo | awk :

real 2m56.282s user 0m38.157s sys 1m31.016s 

@steeldriver “s 변수 대체 / 쉘 매개 변수 확장 :

real 0m0.660s user 0m0.421s sys 0m0.235s 

@jai_s “s IFS-wrangling :

real 1m26.243s user 0m13.751s sys 0m28.969s 

두 제안 모두 내 기존 아이디어보다 크게 개선되었지만 변수 대체가 가장 빠릅니다. 새로운 프로세스를 포크해야합니다.

댓글

  • gnu.org/software/bash/manual / html_node / …
  • 모든 파일 이름을 awk의 한 번 호출로 보내면 순수한 bash의 어떤 솔루션보다 훨씬 빠릅니다.
  • 배열을 사용할 수 없습니다. 한 번에 모두 수행 한 다음 새 배열에 넣습니까?

답변

*/

tmp="${filename#*/}" 

와 일치하는 가장 짧은 선행 하위 문자열을 제거한 다음 가장 긴 /*

답변

 echo $f a/b/c $ (IFS="/";set $f; echo $1) a $ (IFS="/";set $f; echo $2) b $ (IFS="/";set $f; echo $3) c 

와일드 카드가 작동하는 것 같습니다. 큰 따옴표 또는 작은 따옴표-

 f="a?b?c" $(IFS="?"; set $f; echo $1) a echo $f a*b*c (IFS="*"; set $f; echo $1) a 

예, IFS를 다시 기본값으로 설정 해제해야합니다.

 unset IFS 

댓글

  • 좋습니다.
  • 이것은 일반적으로 선호하는 방법이지만 Bash는 이 구문을 사용하여 $1에서 $9까지만 지원합니다. 10 번째 이후 인수의 경우 ${10} 양식을 사용해야합니다.
  • iv id가 ' 일 때 작동하지 않습니다. = “36d3dafb01″>

에는 와일드 카드가 포함됩니다. 그리고 나중에 IFS를 복원해야합니다 (또는 명령 대체에서이 작업을 수행하여 필드 값을 가져 오면 후행 줄 바꿈이 제거됩니다).

  • 이 예제는 Windows의 Git bash 내부에서 분리되어 작동하지만 find 명령에서 파이프하면 다음 오류가 발생합니다. echo: write error: Bad address.
  • 좋아요. 매번 unset IFS해야합니다.
  • 답변

    피드 속도를 높이기 위해 awk에 목록을 추가하세요.

    awk -F "/" "{print $2}" < <(find /usr) awk -F "/" "{print $2}" < inputfile 

    데모 :

    time awk -F "/" "{print $2; SUM++} END {print "number of directories found: " SUM}" < <(find /usr -type d) usr usr . . number of directories found: 16748 real 0m8.910s user 0m0.050s sys 0m0.050s 

    Answer

    이 모든 awk / sed / 대신”dirname “명령을 사용하지 않는 이유 잘라내시겠습니까?

    filename=./foo/bar/baz.xml dirname $filename 

    수익 :

    ./foo/bar 

    댓글

    • 이 경우에는 전체 디렉토리 경로가 아닌 직접적인 디렉토리를 찾고있었습니다.

    답글 남기기

    이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다