grep 사용법

|

Grep

grep는 파일의 내용을 확인해서 찾는 문자열이 포함되었는지 아닌지 찾아주는 명령어입니다. ‘Global Regular Expression Print’의 약어입니다.


사용 방법

grep -r "검색하고 싶은 문자열" /home/pi

-r 옵션은 하위 폴더까지 검색하도록 하는 옵션입니다. /home/pi는 검색 시작 위치입니다.

만약 대소문자 구분을 하지 않으려면 -i 옵션을 사용하면 됩니다. -E 옵션은 파일 내용의 대소문자 차이를 무시하고 정규 표현식으로 검색하는 옵션입니다.


Regular Expression

grep에서 사용할 수 있는 간단한 정규식은 대표적으로 다음과 같습니다.

코드 설명
( ) 그룹화
| 좌우 중 하나
? 직전의 표현이 0회 또는 1회 등장
* 직전의 표현이 0회 이상 연속해서 등장
+ 직전의 표현이 1회 이상 연속해서 등장
. 임의의 한 문자
^ 줄 머리
$ 줄 끝


CustomView 만들기

|

사용자 정의 View

안드로이드에서 CustomView를 만드는 방법입니다.

custom_view.xml

먼저 레이아웃을 작성합니다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:padding="10dp"
  android:orientation="horizontal">

  <ToggleButton
    android:id="@+id/button1"
    android:layout_width="0px"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:textOff="Off"
    android:textOn="On" />

  <ToggleButton
    android:id="@+id/button2"
    android:layout_width="0px"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:textOff="Off"
    android:textOn="On" />

  <ToggleButton
    android:id="@+id/button3"
    android:layout_width="0px"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:textOff="Off"
    android:textOn="On" />

</LinearLayout>


attrs.xml에 속성 추가

그런 다음, CustomView에 대한 속성을 정의합니다. Java 코드 내에서 속성을 지정할 때는 굳이 이런 과정이 필요없지만, XML에서도 속성을 지정하고 싶을 때는 아래와 같이 attrs.xml에 원하는 속성을 지정해야 합니다. attrs.xml 파일은 values 폴더 아래에 위치합니다.

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <declare-styleable name="custom_view">
    <attr format="integer" name="selected" />
  </declare-styleable>
</resources>


CustomView.java

package snowdeer.customviewexample;

import android.content.Context;
import android.content.res.TypedArray;
import android.support.annotation.AttrRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.LinearLayout;
import android.widget.ToggleButton;

public class CustomView extends LinearLayout {

  ToggleButton[] buttons = new ToggleButton[3];
  int selectedId = 0;

  public CustomView(@NonNull Context context,
      @Nullable AttributeSet attrs,
      @AttrRes int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    inflateViews(context, attrs);
  }

  public CustomView(@NonNull Context context,
      @Nullable AttributeSet attrs) {
    super(context, attrs);
    inflateViews(context, attrs);
  }

  void inflateViews(Context context, AttributeSet attrs) {
    LayoutInflater inflater = (LayoutInflater) context
        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    inflater.inflate(R.layout.custom_view, this);

    if (attrs != null) {
      TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.custom_view);
      selectedId = array.getInteger(0, 0);
      array.recycle();
    }
  }

  @Override
  protected void onFinishInflate() {
    super.onFinishInflate();

    buttons[0] = (ToggleButton) findViewById(R.id.button1);
    buttons[1] = (ToggleButton) findViewById(R.id.button2);
    buttons[2] = (ToggleButton) findViewById(R.id.button3);

    setSelected(selectedId);
  }

  public void setSelected(int id) {
    if ((id < 0) || (id > 3)) {
      return;
    }

    selectedId = id;
    for (ToggleButton btn : buttons) {
      btn.setChecked(false);
    }

    buttons[id].setChecked(true);
  }

  public int getSelectedId() {
    return selectedId;
  }

}


활용

이제 CustomView 클래스의 생성이 끝났기 때문에 원하는 곳에서 사용을 하면 됩니다. 예를 들어, activity_main.xml에서 사용을 한다면 다음과 같이 배치해주면 됩니다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical">

  <snowdeer.customviewexample.CustomView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:selected="1" />

</LinearLayout>

SocketAddress 및 SocketAddressFactory 예제

|

SocketAddress.h

#ifndef SNOWSOCKET_SOCKETADDRESS_H
#define SNOWSOCKET_SOCKETADDRESS_H

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cstring>
#include <memory>
#include <w32api/inaddr.h>

using namespace std;

class SocketAddress {
 public:
  SocketAddress(uint32_t address, uint16_t port) {
    getSockAddrIn()->sin_family = AF_INET;
    getSockAddrIn()->sin_addr.s_addr = htonl(address);
    getSockAddrIn()->sin_port = htons(port);
  }

  SocketAddress(string address, uint16_t port) {
    getSockAddrIn()->sin_family = AF_INET;
    getSockAddrIn()->sin_addr.s_addr = inet_addr(address.c_str());
    getSockAddrIn()->sin_port = htons(port);
  }

  SocketAddress(const sockaddr &sockAddr) {
    memcpy(&mSockAddr, &sockAddr, sizeof(sockaddr));
  }

  size_t size() const {
    return sizeof(sockaddr);
  }

 private:
  sockaddr mSockAddr;
  sockaddr_in *getSockAddrIn() {
    return reinterpret_cast<sockaddr_in *> (&mSockAddr);
  }
};

using SocketAddressPtr = shared_ptr<SocketAddress>;

#endif //SNOWSOCKET_SOCKETADDRESS_H


SocketAddressFactory.h

#ifndef SNOWSOCKET_SOCKETADDRESSFACTORY_H
#define SNOWSOCKET_SOCKETADDRESSFACTORY_H

#include <cstdio>
#include <netdb.h>
#include "SocketAddress.h"

using namespace std;

class SocketAddressFactory {
 public:
  static SocketAddressPtr createIPv4SocketAddress(const string &address) {
    string host, service;

    auto pos = address.find_last_of(':');
    if (pos != string::npos) {
      host = address.substr(0, pos);
      service = address.substr(pos + 1);
    } else {
      host = address;
      service = "0";
    }

    addrinfo hint;
    memset(&hint, 0, sizeof(hint));
    hint.ai_family = AF_INET;

    addrinfo *_result = nullptr;
    int error = getaddrinfo(host.c_str(), service.c_str(), &hint, &_result);
    addrinfo *result = _result;

    if (error != 0 && _result != nullptr) {
      freeaddrinfo(result);

      return nullptr;
    }

    while (!_result->ai_addr && _result->ai_next) {
      _result = _result->ai_next;
    }

    if (!_result->ai_addr) {
      freeaddrinfo(result);

      return nullptr;
    }

    auto toRet = make_shared<SocketAddress>(*_result->ai_addr);

    freeaddrinfo(result);

    return toRet;
  }
};

#endif //SNOWSOCKET_SOCKETADDRESSFACTORY_H

arecord 및 aplay 사용방법

|

alsa-utils 설치

사운드를 녹음하는 arecord와 사운드를 재생하는 aplay 프로그램은 alsa-utils에 포함되어 있습니다.

sudo apt-get install alsa-utils

명령어로 두 프로그램을 설치할 수 있습니다.


arecord 사용법

arecord는 다음과 같이 사용할 수 있습니다.

arecord -t raw -c 1 -D plughw:1,0 -f S16_LE -d 5 -r 16000 test.pcm

-t 옵션은 타입으로 다음과 같은 타입을 가집니다.

  • voc
  • wav
  • raw
  • au

-c 옵션은 채널 개수를 의미합니다.

-D 옵션은 디바이스 이름을 의미하며, 위 예제에서는 plughw:1,0이라는 디바이스 이름을 사용했지만, 라즈베리파이에서는 보통 default라는 이름으로 세팅되어 있습니다.

-f 옵션은 포맷(format)을 의미하며 보통 S16_LE 값을 사용하면 됩니다.

-d는 ‘duration’을 의미합니다. 위와 같이 사용하면 5초 동안 녹음합니다.

-r 옵션은 ‘sample-rate’ 값입니다.


aplay 사용법

위에서 녹음한 파일을 재생할 때는 다음과 같은 옵션으로 재생하면 됩니다.

aplay -t raw -c 1 -f S16_LE -r 16000 test.pcm

옵션이 의미하는 바는 arecord와 같습니다.

만약 pcm 파일이 아닌 일반 wav 파일이면 그냥

aplay filename

으로 실행해도 됩니다. wav 파일 안에 헤더 정보가 들어있기 때문입니다.

nano 사용법

|

Nano

리눅스 쉘 기반에서 사용할 수 있는 텍스트 편집기 프로그램 중 하나입니다. 개인적으로는 vi 보다 사용하기 편리한 것 같아서 애용하고 있습니다.


nano 실행 방법

명령어 설명
nano memo.txt memo.txt 파일을 Open
nano -B memo.txt 저장 전에 이전 파일을 ~.filename 으로 백업함
nano -m memo.txt 마우스를 이용해서 Cursor 이동 지원
nano -55 memo.txt memo.txt 파일의 55번 라인부터 시작


편집 모드에서 단축키

편집 모드에서는 방향키나 Ins, Del, Enter 등 다양한 키들을 사용할 수 있습니다.

단축키 설명
Ctrl + O 또는 F3 저장
Ctrl + X 또는 F2 nano 종료 및 저장
Ctrl + W 또는 F6 검색
Ctrl + \ 검색 및 Replace
Ctrl + G 도움말 실행


편집에 관련된 단축키

단축키 설명
Ctrl + K 또는 F9 현재 Line 또는 선택한 텍스트 잘라내기
Ctrl + U 또는 F10 붙여넣기
Ctrl + Y 또는 Page Up 이전 화면
Ctrl + V 또는 Page Down 다음 화면
Ctrl + - 원하는 Line으로 이동
Alt + ( 현재 문단의 시작으로
Alt + ) 현재 문단의 끝으로
Alt + \ 파일의 처음으로
Alt + / 파일의 끝으로