Ruby를 텍스트 처리용 cli 도구로 사용


왜 루비로 한 줄을 해요?
GUI보다 명령줄이 더 효율적인 용례에 익숙하다고 가정합니다.Unix as IDE이라는 제목의 이 시리즈도 참조하십시오.bash과 같은 셸 유틸리티는 내장된 명령과 스크립트 기능을 제공하여 각종 작업을 더욱 쉽게 해결하고 자동화할 수 있다.외부 *nix 명령, 예를 들어 grep, sed, awk, sort, find, parallel, ruby 등은 조합하여 사용할 수 있다.이러한 도구에 대한 익숙도에 따라 ruby -e 'puts readlines.uniq' *.txt을 단독 대체품으로 사용할 수도 있고 특정한 용례에 맞추어 보충할 수도 있습니다.
다음과 같은 일방통행 옵션이 있습니다.
  • ruby -e 'puts readlines.uniq {|s| s.split[1]}' *.txt - 지정된 입력 파일 목록
  • 에서 행을 복사한 경우 복제본만 보관
  • ruby -rcommonregex -ne 'puts CommonRegex.get_links($_)' *.md - 반복 행의 첫 번째 사본만 보관하고 두 번째 필드를 반복 기준으로
  • ruby - 타사 CommonRegexRuby 라이브러리
  • 에서 URL만 추출

  • stackoverflow: merge duplicate key values while preserving order - 최근 질문에 awk보다 더 간단한 ruby 솔루션으로 대답하겠습니다.
  • grep, sed, awk 등 도구에 비해 sed의 주요 장점은 기능이 풍부한 정규 표현식 엔진, 표준 라이브러리와 제3자 라이브러리를 포함한다.awkruby의 문법과 습관용법을 모르면 ruby의 명령행 옵션을 배우는 것이 더 쉽습니다.주요 단점은 이 공구들에 비해 -0[octal]의 속도가 느릴 수 있다는 것이다.

    명령줄 옵션
    선택권
    묘사\0레코드 구분자 지정(-a, 매개 변수가 없는 경우)-n자동 분할 모드(-p 또는 $_($F-c으로 분할)-Cdirectory구문만 확인-d스크립트를 실행하기 전에 디렉터리에 cd를 복사하십시오$DEBUG디버그 플래그 설정(-e 'command'을true로 설정)-e한 줄의 스크립트.-Eex[:in]개 허용.생략 [프로그램 파일]-Fpattern기본 외부 및 내부 문자 인코딩 지정split()-a 자동 분할 모드(-i[extension])ARGV현재 위치에서 -Idirectory개의 파일을 편집합니다(확장자가 있을 경우 백업).$LOAD_PATH-l 디렉토리 지정(여러 번 사용 가능)-n행 끝 처리 사용'while gets(); ... end'스크립트를 중심으로 -p이 순환한다고 가정합니다.-n순환이 sed과 유사하다고 가정하지만 인쇄 줄도 -rlibrary과 유사하다-s스크립트를 실행하기 전에 라이브러리가 필요합니다.-S스크립트 이름 다음에 스위치를 위한 스위치 해석을 사용합니다-vPATH 환경 변수를 사용하여 스크립트 찾기-w버전 번호를 인쇄한 다음 상세 모드를 엽니다-W[level=2|:category]스크립트에 대한 경고 열기-x[directory]경계 레벨 설정하기;0=침묵, 1=중등, 2=지루함--jit# 이전에 텍스트 삭제!디렉터리에 cd가 있을지도 몰라요--jit-[option]기본 옵션을 사용하여 JIT(실험적) 활성화-h옵션을 사용하여 JIT(실험적) 활성화--help이 메시지 표시, ruby 자세히 보기

    루비 코드 실행ruby 프로그램 파일을 실행하려면 파일 이름을 매개 변수로 -e 명령에 전달하는 방법이 있습니다.
    $ echo 'puts "Hello Ruby"' > hello.rb
    $ ruby hello.rb
    Hello Ruby
    
    짧은 프로그램에 대해서도 코드를 매개 변수로 ruby 옵션에 직접 전달할 수 있다.
    $ ruby -e 'puts "Hello Ruby"'
    Hello Ruby
    
    $ # multiple statements can be issued separated by ;
    $ ruby -e 'x=25; y=12; puts x**y'
    59604644775390625
    $ # or use -e option multiple times
    $ ruby -e 'x=25' -e 'y=12' -e 'puts x**y'
    59604644775390625
    

    거르다grep 한 줄 프로그램은regexp와 일치하는 줄을 필터하는 데 사용할 수 있으며 sed, awkruby과 유사하다.많은 명령행 유틸리티와 유사하게 stdingrep과 파일 매개 변수의 입력을 받아들일 수 있다.
    $ # sample stdin data
    $ printf 'gate\napple\nwhat\nkite\n'
    gate
    apple
    what
    kite
    
    $ # print all lines containing 'at'
    $ # same as: grep 'at' and sed -n '/at/p' and awk '/at/'
    $ printf 'gate\napple\nwhat\nkite\n' | ruby -ne 'print if /at/'
    gate
    what
    
    $ # print all lines NOT containing 'e'
    $ # same as: grep -v 'e' and sed -n '/e/!p' and awk '!/e/'
    $ printf 'gate\napple\nwhat\nkite\n' | ruby -ne 'print if !/e/'
    what
    
    기본적으로 sed, awk\n은 입력한 내용을 자동으로 한 줄씩 순환한다(-n을 줄 식별 문자로 한다).이 기능은 -p 또는 ruby 옵션에서 사용할 수 있습니다.앞에서 말한 바와 같이 -e 옵션은 코드를 명령행 매개 변수로 받아들인다.많은 단축키가 필요한 타자량을 줄일 수 있다.
    위의 예에서 정규 표현식 (한 쌍의 빗장 사이의 패턴 정의) 은 입력을 필터하는 데 사용된다.입력 문자열이 조건 상하문에 지정되지 않았을 때 (예: if) 전역 변수 $_에 대한 테스트를 실행합니다. 이 변수는 입력 줄의 내용을 포함합니다. (정확한 용어는 input record입니다.)결론적으로 조건 컨텍스트에서 다음을 수행합니다.
  • /regexp/$_ =~ /regexp/의 바로 가기입니다.
  • !/regexp/$_ !~ /regexp/의 바로 가기입니다.
  • $_print 방법의 기본 매개 변수이다. 이것이 바로 한 줄 프로그램에서 puts 방법보다 우수한 이유이다.이러한 기본값은 print 메서드에 대해 나중에 설명합니다.

    See ruby-doc: Pre-defined global variables for documentation on $_, $&, etc.


    다음은 stdin이 아닌 파일 입력을 사용하는 예입니다.
    $ cat table.txt
    brown bread mat hair 42
    blue cake mug shirt -7
    yellow banana window shoes 3.14
    
    $ # same as: grep -oE '[0-9]+$' table.txt
    $ ruby -ne 'puts $& if /\d+$/' table.txt
    42
    7
    14
    

    대치subgsub 방법으로 수요를 검색하고 교체합니다.기본적으로 입력 문자열이 제공되지 않을 때, 이 방법은 $_에서 실행됩니다.이러한 예제에서는 -p 옵션 대신 -n 옵션을 사용하여 각 입력 줄을 처리한 후 $_ 값을 자동으로 인쇄합니다.
    $ # for each input line, change only first ':' to '-'
    $ # same as: sed 's/:/-/' and awk '{sub(/:/, "-")} 1'
    $ printf '1:2:3:4\na:b:c:d\n' | ruby -pe 'sub(/:/, "-")'
    1-2:3:4
    a-b:c:d
    
    $ # for each input line, change all ':' to '-'
    $ # same as: sed 's/:/-/g' and awk '{gsub(/:/, "-")} 1'
    $ printf '1:2:3:4\na:b:c:d\n' | ruby -pe 'gsub(/:/, "-")'
    1-2-3-4
    a-b-c-d
    
    $_ 방법을 사용하지 않은 상태에서 !을 어떻게 수정하는지 알고 싶을 수도 있습니다.왜냐하면 이러한 방법은 내부 핵의 일부이기 때문이다(자세한 정보는 ruby-doc: Kernel 참조). -n 또는 -p 옵션을 사용할 때만 사용할 수 있다.
  • sub(/regexp/, repl)$_.sub(/regexp/, repl)의 바로 가기이며, 교체에 성공하면 $_이 업데이트됩니다.
  • gsub(/regexp/, repl)$_.gsub(/regexp/, repl)의 바로 가기이며, 교체에 성공하면 $_이 업데이트됩니다.

    현장 처리
    아래에 표시된 예시 입력 파일을 고려하십시오. 그 중 필드는 공백 문자로 구분됩니다.
    $ cat table.txt
    brown bread mat hair 42
    blue cake mug shirt -7
    yellow banana window shoes 3.14
    
    다음은 전체 행이 아닌 특정 필드에 기반한 예들입니다.-a 옵션을 사용하면 입력 줄이 공백을 기반으로 분할되고 $F 글로벌 변수를 사용하여 필드 내용에 접근할 수 있습니다.선행 및 후행 공백이 억제되어 빈 필드가 생성되지 않습니다.
    $ # print the second field of each input line
    $ # same as: awk '{print $2}' table.txt
    $ ruby -ane 'puts $F[1]' table.txt
    bread
    cake
    banana
    
    $ # print lines only if last field is a negative number
    $ # same as: awk '$NF<0' table.txt
    $ ruby -ane 'print if $F[-1].to_f < 0' table.txt
    blue cake mug shirt -7
    
    $ # change 'b' to 'B' only for the first field
    $ # same as: awk '{gsub(/b/, "B", $1)} 1' table.txt
    $ ruby -ane '$F[0].gsub!(/b/, "B"); puts $F * " "' table.txt
    Brown bread mat hair 42
    Blue cake mug shirt -7
    yellow banana window shoes 3.14
    

    시작과 끝
    입력을 읽기 전에 어떤 작업을 수행해야 할 때는 BEGIN{} 블록을 사용하고, 모든 입력을 처리한 후에는 END{} 블록을 사용하여 어떤 작업을 수행할 수 있다.
    $ # same as: awk 'BEGIN{print "---"} 1; END{print "%%%"}'
    $ # note the use of ; after BEGIN block
    $ seq 4 | ruby -pe 'BEGIN{puts "---"}; END{puts "%%%"}'
    ---
    1
    2
    3
    4
    %%%
    

    환경 해시
    자동화와 스크립트 작성은 일반적으로 사용자의 입력, 파일, 셸 명령 출력 등을 받아들일 수 있는 명령을 구성해야 한다. 앞에서 말한 바와 같이 이 책은 bash을 셸로 사용한다고 가정한다.셸의 환경 변수에 접근하려면 환경 변수의 이름을 문자열 키로 사용하여 특수한 해시 변수 ENV을 호출할 수 있습니다.
    $ # existing environment variable
    $ # output shown here is for my machine, would differ for you
    $ ruby -e 'puts ENV["HOME"]'
    /home/learnbyexample
    $ ruby -e 'puts ENV["SHELL"]'
    /bin/bash
    
    $ # defined along with ruby command
    $ # note that the variable is placed before the shell command
    $ word='hello' ruby -e 'puts ENV["word"]'
    hello
    $ # the input characters are preserved as is
    $ ip='hi\nbye' ruby -e 'puts ENV["ip"]'
    hi\nbye
    
    다음은regexp가 환경 변수 콘텐츠로 전달될 때의 또 다른 예입니다.
    $ cat word_anchors.txt
    sub par
    spar
    apparent effort
    two spare computers
    cart part tart mart
    
    $ # assume 'r' is a shell variable that has to be passed to the ruby command
    $ r='\Bpar\B'
    $ rgx="$r" ruby -ne 'print if /#{ENV["rgx"]}/' word_anchors.txt
    apparent effort
    two spare computers
    

    As an example, see my repo ch: command help for a practical shell script, where commands are constructed dynamically.



    외부 명령 실행system 내부 핵 방법으로 외부 명령을 호출할 수 있다.문서를 보려면 ruby-doc: system을 참조하십시오.
    $ ruby -e 'system("echo Hello World")'
    Hello World
    
    $ ruby -e 'system("wc -w <word_anchors.txt")'
    12
    
    $ ruby -e 'system("seq -s, 10 > out.txt")'
    $ cat out.txt
    1,2,3,4,5,6,7,8,9,10
    
    반환값 system 또는 전역 변수 $?은 명령의 종료 상태를 조작하는 데 사용할 수 있습니다.
    $ ruby -e 'es=system("ls word_anchors.txt"); puts es'
    word_anchors.txt
    true
    $ ruby -e 'system("ls word_anchors.txt"); puts $?'
    word_anchors.txt
    pid 6087 exit 0
    
    $ ruby -e 'system("ls xyz.txt"); puts $?'
    ls: cannot access 'xyz.txt': No such file or directory
    pid 6164 exit 2
    
    외부 명령의 결과를 저장하려면 백틱스 또는 %x을 사용합니다.
    $ ruby -e 'words = `wc -w <word_anchors.txt`; puts words'
    12
    
    $ ruby -e 'nums = %x/seq 3/; print nums'
    1
    2
    3
    

    See also stackoverflow: difference between exec, system and %x() or backticks



    요약
    본고는 ruby cli가 사용하는 흔한 옵션과 전형적인 cli 텍스트 처리 예시를 소개한다.grep, sed, awk 등 특정 용도의 cli 도구는 보통 속도가 빠르지만 ruby은 더욱 광범위한 표준 라이브러리와 생태계를 가지고 있다.만약 당신이 ruby에 익숙하지만, 이러한 cli 도구에 익숙하지 않다면, 너무 많은 것을 배울 필요가 없습니다.

    Ruby one liners 레시피
    만약 당신이 이 글을 좋아하고 더 많은 정보를 알고 싶다면, 아래의 링크를 사용하여 나의 전자책을 보십시오.이번 주 일요일(2020년 10월 4일)까지 무료로 내려받을 수 있다.
  • https://gumroad.com/l/ruby-oneliners
  • https://leanpub.com/ruby-oneliners
  • 또한 다음 링크를 사용하여 Ruby 텍스트 처리 패키지에서 전자책을 가져올 수도 있습니다.
  • https://gumroad.com/l/ruby-textprocessing
  • https://leanpub.com/b/ruby-textprocessing
  • 좋은 웹페이지 즐겨찾기