파이썬은 문자열을 다룰때 다양한 형태로 문자열을 다룰 수 있습니다. C나 Java같은 언어에서는 문자열을 쌍따옴표로 둘러싸서 문자열을 표현하지만 파이썬은 ', ", ''' 로 둘러싸서 문자열을 표현할 수 있죠. 이렇게하는 이유는 ', " 가 문자열에 글자로 표현될 때 문자열의 종료나 시작으로 인식하지 않게 하기 위함입니다.

str1 = 'python'
str2 = "python"
str3 = '''python'''

print (str1, str2, str3)

str1 = '"python"'
str2 = "'python'"
str3 = '''"python"'''

print ( str1, str2, str3)
python python python
"python" 'python' "python"

 

이제부터 파이썬의 문자열에 대해서 알아보도록 하겠습니다. 

문자열 포맷

- 포맷 문자를 통한 문자열 포맷

C와 같이 문자열에 다른 데이터를 포함시키려면 format 문자를 사용해서 정수든, 글자든 입력받을 수가 있죠.

포맷 문자 설명
%d 10진수 정수 (Decimal)
%c 문자 (Character)
%f 부동 소수 (Floating Point)
%o 8진수 정수 (Octal)
%x 16진수 정수 (Hexadecimal)
%s 문자열 (String)
%% % 문자

 

C에서 지원하는 무자열 형태의 format은 거의다 지원한다고 보시면됩니다. 그렇기 때문에 아래의 링크를 통해서 더 많은 문자열 포맷을 활용하는 방법을 알아보시기 바랍니다.

reakwon.tistory.com/169

 

[C언어] 출력 형식(format) 총정리 (Feat. sprintf, fprintf) - 일정한 간격으로 문자열 출력 예제 까지

C언어의 다양한 출력 문자들 C언어에서 다양한 출력 형식을 지원합니다. 우리가 너무나 잘 알고 있는 부호있는 정수형은 %d, 문자열 출력은 %s 등이 그 출력형식인데요. 오늘은 자세하게 한번 총

reakwon.tistory.com

 

형식을 지정할 데이터는 문자열 끝 %를 이용해서 나열해줍니다.

print ('구구단 2단')
for i in range(10):
    print ('%d * %d = %d' % (2, i, 2*i) )
구구단 2단
2 * 0 = 0
2 * 1 = 2
2 * 2 = 4
2 * 3 = 6
2 * 4 = 8
2 * 5 = 10
2 * 6 = 12
2 * 7 = 14
2 * 8 = 16
2 * 9 = 18

 

- format함수를 통한 문자열 포맷

이와 같은 방식은 우선 자료형에 따른 포맷 문자를 알고있어야하는 단점이 있습니다. 파이썬 3부터는 포맷을 알고 있지 않아도 사용할 수 있는 방법은 format함수를 사용할 수 있습니다. 여기서 중괄호를 이용합니다. 숫자를 입력하여 차례대로 입력받을 수도 있고, 명시적으로 이름을 지정해서 사용할 수도 있습니다.

str = 'str.{} example'.format('format')
print(str)
                                                #  {0}      {1}        {2}          {3}
str = 'SELECT {0} FROM {1} WHERE {2} = {3}'.format('*', 'accounts', 'email', 'reakwon@gmail.com')
print (str)

str = 'name : {name}, age : {age}'.format(name='kim',age=22)
print (str)
str.format example
SELECT * FROM accounts WHERE email = reakwon@gmail.com
name : kim, age : 22

 

- f String을 사용한 문자열 포맷

문자열을 저장할때 가장 맨 앞에 f를 준 후 변수명을 그대로 문자열에 중괄호로 입력하면 그 변수명의 데이터가 그대로 문자열에 입력됩니다. f는 format의 약자라는 점은 참고해주세요. 이 f string은 파이썬 3.6부터 지원합니다.

name = 'shin'
age = 22
score = 80

result = f'name : {name}, age : {age}, score : {score}'
print (result)
name : shin, age : 22, score : 80

 

산술 연산도 할 수 있습니다.

a = 10
b = 20

fstr = f'{a} * {b} = {a*b}, {a} + {b} = {a+b}'
print (fstr)
10 * 20 = 200, 10 + 20 = 30

 

함수의 반환값도 쓸수 있죠.

def mult(a, b):
    return a*b

def add(a, b):
    return a+b

a = 5
b = 9
fstr = f'{a} * {b} = {mult(a,b)}, {a} + {b} = {add(a,b)}'
print (fstr)
5 * 9 = 45, 5 + 9 = 14

 

문자열 메소드

문자열 메소드는 엄청 많은데, 그 중에서 몇가지 문자열 메소드를 알아보도록 하겠습니다. 문자열은 아래의 문자열을 사용해보지요.

paul_rand = 'Do not to be original, just-try-to-be-good.'

 

- 문자열 길이 : len

문자열 내장 메소드는 아니지만 길이를 알고자 하는 경우 len 내장 함수를 쓰면 됩니다.

print(len(paul_rand))
43

 

- 문자수 세기 : count

문자나 문자열의 수를 새려면 count 메소드를 사용하여 확인할 수 있습니다.

print (paul_rand.count('t'))        #t문자 세기
print (paul_rand.count('to'))      #to 문자열 세기
5
2

 

- 대소문자로 변경 : upper, lower, casefold

알파벳을 모두 소문자로 변경하려면 lower 메소드 사용하면 되는데 소문자로 변경하는 메소드는 casefold라는 메소드도 있습니다. 반대로 모두 대문자로 변경하려면 upper를 사용하면 됩니다.

print (paul_rand.upper())   #모두 대문자로 변경
print (paul_rand.lower())   #모두 소문자로 변경
print (paul_rand.casefold())
DO NOT TO BE ORIGINAL, JUST-TRY-TO-BE-GOOD.
do not to be original, just-try-to-be-good.
do not to be original, just-try-to-be-good.

 

- 문자열 분리 : split

문자열을 공백, 또는 지정된 나누려고 구분된 구분자에 따라서 문자열을 쪼개고 싶다면 split 메소드를 사용할 수 있습니다. 인자를 넣어주지 않는다면 공백을 기준으로 나누고, 지정한 문자열을 넘겨주면 그 문자열을 기준으로 문자열을 나눕니다. 쪼개어진 문자열들은 리스트 형태로 넘겨줍니다.

tokens = paul_rand.split()
print (tokens)

tokens = paul_rand.split('-')
print (tokens)
['Do', 'not', 'to', 'be', 'original,', 'just-try-to-be-good.']
['Do not to be original, just', 'try', 'to', 'be', 'good.']

 

- 문자열 공백 지우기 : strip, lstrip, rstrip

문자열에 공백을 제거하려면 strip 메소드를 사용하면 됩니다. 특별히 왼쪽 공백은 lstrip, 오른쪽 공백은 rstrip을 사용하면 됩니다.

str = '  __name__  __main__    '

print (str.lstrip())    # 왼쪽 공백 제거
print (str.rstrip())    # 오른쪽 공백 제거
print (str.strip())     # 양쪽 공백 제거
__name__  __main__    
  __name__  __main__
__name__  __main__

 

- 문자열 위치 : find, index, rfind, rindex

문자열에서 특정 문자열이 어느 위치에 있는지 확인하려면 find와 index를 사용하면 됩니다. 이때 가장 첫번째로 등장한 위치를 반환합니다. find와 index의 차이점은 문자를 찾지 못할때는 에러를 발생시키느냐 마냐입니다. find는 못찾으면 -1을 반환하고 index는 에러를 발생시킵니다.

print ('o : ', paul_rand.find('o'))
print ('. : ', paul_rand.index('.'))
print ('original : ', paul_rand.find('original'))
print ('just : ' ,paul_rand.index('just'))

print ('6 :', paul_rand.find('6'))      #없는 문자열의 경우 -1 반환
print ('6 :', paul_rand.index('6'))     #없는 문자열의 경우 에러

o :  1
. :  42
original :  13
just :  23
6 : -1
Traceback (most recent call last):
  File "C:\Users\grjwu\PycharmProjects\pythonProject1\main.py", line 9, in <module>
    print ('6 :', paul_rand.index('6'))
ValueError: substring not found

 

또는 start와 end 인덱스를 지정하게 되면 그 부분에 대해서만 찾아오게 됩니다.

print (paul_rand.find('to',4,9))    # 글자위치 4부터 9 전까지 탐색
print (paul_rand.index('or',10,19)) # 글자위치 10부터 19 전까지 탐색
7
13

 

왼쪽이 아니라 오른쪽에서 찾아보고 싶다면 rfind와 rindex를 사용하면 됩니다. 이때 결과는 위의 index와 find와 동일하며 오류내는 것도 동일합니다.

good = 'good, good, good~'

print ('o : ', good.rfind('o'))
print ('g : ', good.rindex(','))
o :  14
g :  10

 

 

- 문자열 변경 : replace

특정 문자열을 변경하고 싶다면 replace메소드를 사용하여 바꿀 수 있습니다.

print (paul_rand.replace('to','TO'))
Do not TO be original, just-try-TO-be-good.

 

- 특정 문자열로 시작하느냐 끝나느냐 - startswith, endswith

우리가 지정한 문자열로 시작하느냐를 알아보고 싶다면 startswith, 끝이 나는가를 알아보려면 endswith 메소드를 사용하면 됩니다. 지정된 문자열로 시작, 끝이 나면 True를, 아니면 False를 반환합니다.

print (paul_rand.startswith('Do'))
print (paul_rand.endswith('.'))

print (paul_rand.startswith('The'))
print (paul_rand.endswith('!'))
True
True
False
False

 

- 문자열 삽입 : join

특정 문자열을 문자마다 삽입하고 싶다면 join을 사용하면 됩니다. 글자마다 우리가 지정한 문자열이 삽입되고 만약 단어마다 문자열 삽입을 원한다면 리스트 형태의 문자열 리스트를 전달해주면 됩니다.

 

str = 'ABCDE'
print ("=".join(str))

str = ['Apple','Banana','Cherry']
print (', '.join(str))
A=B=C=D=E
Apple, Banana, Cherry

 

- 탭 간격 조정 : expandtabs

탭의 간격을 조정하는 메소드는 expandtabs입니다. 

str = "h\te\tl\tl"
print (str)
print (str.expandtabs(2))
print (str.expandtabs(4))
print (str.expandtabs(10))
h	e	l	l
h e l l
h   e   l   l
h         e         l         l

 

여기까지 파이썬 문자열의 활용방법과 메소드 들에 대해서 알아보았습니다. 여기서 소개하지 않은 메소드도 많이 있으므로 그때 그때 구글링하여 사용하시기 바랍니다.

반응형
블로그 이미지

REAKWON

와나진짜

,

 

 

find

find 명령어는 리눅스를 사용함에 있어서 아주 유용한 기능을 제공해주는 명령어입니다. 말 그대로 우리가 원하는 파일이나 디렉토리를 찾아줍니다. 윈도우로 따진다면 아래의 입력란이 되겠지요.

윈도즈에서는 아래에 파일명을 치면 검색이 가능하지만 리눅스에서는 find라는 명령어를 통해서 파일을 찾을 수 있습니다. 잘만 사용하면 너무나 편리한 명령어이기도 합니다.

하지만 find명령은 너무나 사용하기에 광범위한 명령어이므로 그 중 자주 사용되는 몇가지만 소개하도록 하겠습니다.

 

이제부터 find 명령을 통해서 어떻게 파일을 찾을 수 있을지 알아보겠습니다.

 

1) 기본적인 파일 찾기

find는 기본적으로 찾을 파일 경로와 이름으로 구성되면 정말 그 파일만 찾는 기능을 할 수 있습니다. 아래 처럼 말이지요.

#find /home -name "test.c" 

설명

/home : 파일을 찾을 디렉토리를 지칭합니다.

-name "test.c" : test.c 파일을 찾습니다. 

 

결과

/home/centos/code/test.c
/home/centos/test.c

 

2) 와일드카드(*)를 이용한 단어를 포함한 파일 찾기

find 명령어는 파일이름에 와일드카드 문자(*)를 포함하여 특정 단어를 포함하는 파일을 찾을 수 있습니다.

#find /home -name "*test*"

설명

/home : 파일을 찾을 디렉토리입니다.

-name "*test*" : test라는 단어를 포함하는 파일을 찾습니다. ttest이든, test.c이든, aatestbb 파일이든 전부 찾아줍니다.

 

결과

/home/centos/code/test.c
/home/centos/test.c
/home/centos/patience_test.c

 

3) -type 옵션으로 파일의 타입을 포함하여 찾기

저는 test라는 디렉터리를 하나 만들었고 여기서 test라는 단어를 포함하는 디렉터리를 찾아보도록 하겠습니다.

/home/centos/code/test.c
/home/centos/test.c
/home/centos/patience_test.c
/home/centos/test <- directory
#find /home -name "*test*" -type d

설명 

-type d : 파일 type이 디렉터리인것만 찾습니다.

 

결과

/home/centos/test

파일 타입은 다음과 같습니다.

option type
f regular file
d directory
c character special
b block special
l symbolic link
s socket
p fifo

 

4) 파일의 크기에 따른 파일 검색

-size 옵션으로 파일의 크기를 검색할 수 있습니다. 파일 크기 앞에 '+'를 붙이면 그 크기 초과, '-'를 붙이면 그 크기 미만으로 검색이 됩니다. 또한 파일 크기 뒤에 단위가 붙는데요. 아래와 같습니다. 단위를 생략하면 기본적으로 리눅스 블록(b)이 단위가 됩니다.

(b:block, c:bytes, w:2bytes, k:kbytes, M:mbytes, G:gbytes)

옵션 단위
c 1byte 단위
b 1block 단위(1block = 512 bytes)
w 2 bytes 단위
k 1 kilobytes
M 1 metabytes
G 1 gigabytes

몇 가지 예제)

find /home -size 1k 크기가 1k인 파일 검색
find /home -size +100M 100M 초과인 파일 검색
find /home -size -1G 1G 미만인 파일 검색
find /home -size +100M -size -2G 100M 초과 2G 미만인 파일 검색

 

 

5) exec으로 찾을 파일에 명령어 실행

-exec으로 명령어를 실행할 수 있습니다.

find명령을 통한 파일들은 모두 {}에 담겨지게 됩니다. 그러니까 ls -al {} 또는 ls {} -al 인 것이고, cp {} . 인것이 왜인지 생각해보세요.

ls -al {파일}, 또는 ls {파일} -al은 같은 결과를 갖습니다. 전달받는 파일 인자는 1개이니까요 .

반대로 cp는 2개의 파일 인자를 받습니다. 첫번째 인자는 복사가 될 파일, 두번째 인자는 복사가 될 위치이지요. 그래서 cp {파일} . 가 됩니다.

명령어 끝은 항상 \;으로 끝나야합니다. 프로그래밍을 하는 분이라면 ;이 연산의 종료를 의미한다는 것을 아실겁니다. ';'은 특수문자이기 때문에 escape(특수문자화 하지 않는 것)하기 위해 \를 같이 사용합니다. 이해가 안된다면 그냥 외우시거나 프로그래밍 언어를 배우시는 것을 추천드립니다. ㅎㅎㅎ 

 

예제를 통해서 살피도록 하겠습니다.

 

예제 1) 

find /home -name "*test*" -exec ls -al {} \;

설명

test라는 단어가 포함된 파일을 대상으로 ls -al을 실행합니다. {}의 위치를 잘봐두세요.

 

결과

-rw-r--r--. 1 root root 313  2월 29 02:37 /home/centos/code/test.c
-rw-r--r--. 1 root root 0  3월  3 06:57 /home/centos/test.c
-rw-r--r--. 1 root root 0  3월  3 07:04 /home/centos/patience_test.c
합계 4
drwxr-xr-x.  2 root   root      6  3월  3 07:08 .
drwx------. 17 centos centos 4096  3월  3 07:34 ..

 

예제 2)

find /bin/ -name "*gr*" -exec cp {} /home/centos  \;

설명

bin 하위의 gr이라는 파일이나 디렉토리를 복사해 /home/centos로 위치합니다. 실제 실행하고 나서 /home/centos에 위치하여 결과를 보면 이런 파일들이 존재합니다.

 

결과

bzegrep            groff                  grub2-mkstandalone  xzfgrep
bzfgrep            grops                  grub2-script-check  xzgrep
bzgrep             grotty                 grub2-syslinux2cfg  zegrep
chgrp              groups                 lexgrog             zfgrep

..생략..

이뿐만 아니라 rm, mv 등의 명령도 실행 가능합니다. rm은 쓸때 꼭 주의하세요.

 

예제 3)

아까 옮겼던 gr이 포함된 단어의 파일들을 전부 삭제해보도록 하겠습니다.(우선 그전에 gr이 포함된 파일 중 원래 그 자리에 있었던 파일이 있는지 확인하세요.)

find /home/centos/ -name "*gr*" -exec rm -rf {} \;

설명

찾은 파일에 대해서 강제 삭제 명령(rm -rf)을 하게 됩니다. 이 명령어는 전달되는 파일이 하나밖에 없으므로 {}이 어디에나 위치해도 됩니다. rm -rf {} 이건 rm {} -rf이건 상관이 없다 이거죠. 허나 반드시 이 명령어를 실행하지 마시기바랍니다. 잘못하면 진짜 ㅈ돼요.

 

결과

gr이 포함된 모든 파일이 삭제되었습니다.

 

6) 특정 단어 또는 내용을 갖는 파일을 검색하기

끝에 파이프를 연결해서 | xargs grep "검색할 내용"을 덧붙이면 되는데 에러 또는 경고까지 전부 출력하므로 에러(2)는 전부 쓰레기통(/dev/null)에 버려 출력하지 않게 합시다.

find / -name "*.c*" -type f | xargs grep "#include" 2>/dev/null

설명

/디렉토리부터 확장자가 c를 포함하며 파일은 정규파일을 검색합니다.  그때 #include라는 문자열을 포함하는 파일만 검색하며 오류 출력은 전부 쓰레기통인 /dev/null로 갖다 버립니다.

 

결과

뭐 이런것들이 보이네요.

/usr/lib/firmware/isci/create_fw.c:#include 
/usr/lib/firmware/isci/create_fw.c:#include 
/usr/lib/firmware/isci/create_fw.c:#include 
/usr/lib/firmware/isci/create_fw.c:#include <sys/types.h>
/usr/lib/firmware/isci/create_fw.c:#include <sys/stat.h>
/usr/lib/firmware/isci/create_fw.c:#include 
/usr/lib/firmware/isci/create_fw.c:#include 
/usr/lib/firmware/isci/create_fw.c:#include 
/usr/lib/firmware/isci/create_fw.c:#include <asm/types.h>
/usr/lib/firmware/isci/create_fw.c:#include 

... 생략 ...

 

 

 

7) 특정 권한을 갖는 파일 찾기

-perm 옵션으로 어떤 파일이 어떤 권한이 있는지 검색할 수 있습니다. 

find . -perm 777

설명

위의 명렁은 유저 권한으로 읽기, 쓰기 , 실행 그리고 그룹 권한으로 읽기, 쓰기, 실행 마지막으로 다른 유저 권한으로는 읽기, 쓰기, 실행 권한인 파일을 모조리 찾는 명령어입니다.

만일 -perm 644라면 유저 권한으로 읽기,쓰기 그룹 권한으로 읽기, 다른 유저 권한으로 읽기의 파일들을 전부 찾습니다.

 

8) 끝까지 찾지 않아도 되는 maxdepth

maxdepth는 찾는 깊이를 뜻합니다. find명령어는 기본적으로 지정된 디렉토리 밑으로 끝까지 search합니다. 만약 maxdepth 옵션을 준다면 지정된 깊이까지만 파일을 검색합니다. 깊이라함은 하위디렉토리를 뜻합니다.

maxdepth의 0은 자기 자신을 의미합니다.

 find / -maxdepth 1

설명

/디렉토리에서 깊이가 1인 파일들만 검색합니다. 결과는 다음과 같습니다.

 

결과

/
/dev
/proc
/run
/swap
/sys
/etc
/root
/var
/usr
/bin
/sbin
/lib
/lib64
/boot
/home
/media
/mnt
/opt
/srv
/tmp

 

지금까지 제가 현업에서 자주 사용하는 find명령어의 옵션을 살펴보았는데요. 가만히보면 이외의 명령어를 사용할 일이 별로 없었습니다. 다른 분들은 잘 모르겠네요. 

 

기능도 막강하고 배우기에는 너무 범위가 넓은 find 명령어는 알면 알 수록 흥미있는 명령어인것 같습니다. 제가 모르거나 놓친 부분이거나, 또는 많이 사용하지만 이곳에 나오지 않은 옵션이라면 댓글 달아주세요!

 

나머지 기능은 꾸준히 업데이트하여 올리도록 하겠습니다.

 

 

반응형
블로그 이미지

REAKWON

와나진짜

,