Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

Ruby로 Command-Line-Fu 레벨 올리기

명령줄을 실제로 마스터하려면 수백은 아니더라도 수십 개의 작은 유틸리티 프로그램을 마스터해야 합니다. 이들 각각은 약간 다르게 일을 합니다. 꽤 압도적일 수 있습니다.

다행히도 이러한 많은 단일 목적 도구를 Ruby와 같은 범용 프로그래밍 언어로 대체할 수 있습니다. 그렇게 하면 이미 명령줄 수준을 높이는 데 필요한 Ruby 지식을 사용할 수 있습니다.

이 게시물은 Ruby를 명령줄 스위스 군용 칼로 사용하는 기본 사항을 안내합니다. 나는 똑똑한 한 줄로 당신을 폭격하지 않을 것입니다. 대신 우리는 실제로 어떻게 작동하는지 살펴보고 이러한 기술을 적용하여 자신의 문제를 해결할 수 있기를 바랍니다.

명령줄에서 Ruby 사용

다음과 같이 명령줄에서 Ruby 프로그램을 실행할 수 있다는 것을 알고 있을 것입니다.

$ ruby myprogram.rb

그러나 Ruby에서 실행할 코드를 파이프할 수 있다는 것을 알고 계셨습니까?

$ echo "puts 2+2" | ruby
4

훨씬 더 유용한 것은 코드를 명령줄 인수로 전달하는 기능입니다. 이것이 오늘 우리가 할 시간입니다.

$ ruby -e 'puts 2+2'
4

안녕 초보자

위의 예가 혼란스럽습니까? 파이프와 리디렉션에 익숙하지 않기 때문일 수 있습니다. 좋은 소개를 위해 이 포스트를 확인하십시오. 우리는 아래에서 파이프를 많이 사용할 것입니다.

입력 작업

대부분의 명령줄 도구는 일부 데이터를 가져와 처리한 다음 다시 내보냅니다.

입력을 받기 위한 두 가지 좋은 옵션이 있습니다. 명령줄 인수와 STDIN입니다. 각각을 살펴보겠습니다.

명령줄 인수

스크립트에 원하는 만큼 명령줄 인수를 보낼 수 있습니다. 다른 모든 것 뒤에 붙이세요:

$ ruby -e '<your code here>' arg1 arg2 arg3 etc

이러한 인수는 ARGV 내부에 저장됩니다. 정렬. 아래 예에서는 그 안에 무엇이 들어 있는지 볼 수 있도록 전체 배열을 덤프하고 있습니다.

$ ruby -e 'puts ARGV.inspect' apples bananas pears oranges
["apples", "bananas", "pears", "oranges"]

이것이 바로 Ruby가 항상 동작하는 방식이라는 점은 주목할 가치가 있습니다. 명령줄을 사용한다고 해서 마법 같은 일이 일어나지는 않습니다. 자세한 내용은 ARGV에 대한 이 게시물을 확인하세요.

바보 예

내가 매우 이기적이라고 잠시 상상해보십시오. 나에게 가장 중요한 것은 웹상에서 내 이름이 몇 번이나 언급되는지 아는 것입니다. 우리가 본 기술을 사용하여 모든 웹 페이지에 대해 이것을 계산하는 하나의 라이너를 쉽게 작성할 수 있습니다.

$ ruby -e "require 'open-uri'; puts open(ARGV.first).read.scan(/starr/i).count" <url here>

STDIN

명령줄 인수는 훌륭하지만 짧은 값에만 적합합니다. Moby Dick의 축약되지 않은 텍스트를 입력하는 데 사용하고 싶지 않을 것입니다. 이를 위해 STDIN을 사용하고자 합니다.

STDIN에 익숙하지 않더라도 겁먹지 마십시오. 여기서는 읽기용으로 열려 있는 다른 파일처럼 작동합니다.

여기 내가 의미하는 바입니다. 아래 예에서는 일부 텍스트를 Ruby로 파이핑하고 있습니다. Ruby 스크립트는 STDIN에서 이를 읽고 화면에 인쇄합니다.

echo "bananas!" | ruby -e "puts STDIN.read"
bananas!

cat를 사용하여 더 많은 양의 데이터를 쉽게 입력할 수 있습니다. . 아래 예는 first를 사용합니다. 텍스트의 처음 몇 줄을 가져오기 위해 모든 파일에서 사용할 수 있는 메서드:

cat moby.txt | ruby -e "puts STDIN.first(3)"
Call me Ishmael. Some years ago--never mind how long precisely--having
little or no money in my purse, and nothing particular to interest me on
shore, I thought I would sail about a little and see the watery part of

바보 예

이제 STDIN을 사용하는 방법을 알았으므로 위의 멍청한 예제를 다시 작성해 보겠습니다. Ruby를 사용하여 웹페이지를 가져오는 대신 curl을 사용할 수 있습니다. 패턴 매칭에는 Ruby만 사용하세요.

curl <MY URL> | ruby -e "puts STDIN.read.scan(/starr/i).size"

구문 설탕이 포함된 STDIN!

STDIN으로 작업할 때 입력의 각 줄을 반복해야 하는 것은 매우 일반적입니다. 디렉토리의 모든 파일에 대한 파일 확장자를 얻고 싶다고 상상해보십시오. 다음은 일반 STDIN 루프를 사용하여 수행하는 방법입니다.

ls | ruby -e 'STDIN.each_line { |l| puts l.split(".").last }'
rb
rb
csv

STDIN 루프가 너무 일반적이기 때문에 Ruby는 약식을 제공합니다. -n으로 스크립트를 실행하면 플래그를 지정하면 Ruby는 STDIN의 각 줄을 자동으로 반복합니다. 현재 줄은 전역 변수 $_에 있습니다. .

따라서 위의 예를 다음과 같이 다시 작성할 수 있습니다.

ls | ruby -n -e 'puts $_.split(".").last'

속기 사용 여부는 사용자에게 달려 있습니다. 코드를 적게 작성해야 한다는 것은 분명하지만 -n과 같은 임의의 사실을 더 많이 기억해야 한다는 의미이기도 합니다. 및 $_ .

출력 작업

이와 같은 상황에서는 일반적으로 출력을 STDOUT에 쓰고 싶을 것입니다. 이렇게 하면 출력을 다른 프로그램으로 파이프하거나 필요에 따라 디스크로 리디렉션할 수 있으므로 유연성이 극대화됩니다.

좋은 소식은 아마도 매우 친숙한 동일한 인쇄 명령을 사용할 수 있다는 것입니다. 하지만 한 가지 주의해야 할 점은 puts 원하는 것일 수도 있고 아닐 수도 있는 개행을 추가합니다.

puts "hello world" # sends "hello world\n" to STDOUT
print "hello world" # doesn't add a newline"

모두 합치기

Honeybadge는 미국 워싱턴 주에 본사를 두고 있습니다. 이는 워싱턴에 거주하는 모든 유료 고객에 대해 판매세를 납부할 수 있는 특권이 있음을 의미합니다.

나는 이것을 상당히 단순화했지만 기본적으로 해당 연도의 모든 거래에 대한 CSV 파일이 있습니다. 다음과 같이 보입니다.

1/1/2015,100.00,WA
1/1/2015,50.00,NY

따라서 워싱턴의 모든 거래에 대한 빠른 합계를 얻으려면 다음과 같이 한 줄짜리를 사용할 수 있습니다.

$ cat cc.csv | ruby -e 'puts STDIN.inject(0) { |sum, x| date, amount, state = x.split(","); state.strip == "WA" ? sum + amount.to_f : sum  }'

이것은 CSV 파일을 구문 분석하는 끔찍하게 조잡한 방법임을 명심하십시오. 나는 결코 이 코드를 야생으로 보내지 않을 것입니다. 그러나 일회성 문제를 해결하기 위해 아주 작은 프로그램을 작성하는 즐거움 중 하나는 모든 극단적인 경우를 무시할 수 있다는 것입니다. 그것이 내가 여기서 할 일입니다.