bash script 질문입니다 (sorting).

aeronova의 이미지

안녕하세요,

급하게 쓴다고 bash script를 만들어서 사용중인데, 약간의 사소한 문제가 있어서 질문드립니다.

우선 제가 다음과 같은 파일들을 가지고 있습니다.

 liftingline_div_N10.dat
 liftingline_div_N15.dat
 liftingline_div_N20.dat
 liftingline_div_N25.dat
 liftingline_div_N5.dat

제가 하려고 하는 것은 각 파일을 그냥 쭉 연결시켜 하나의 파일에 담는 것입니다. 이것을 하기 위해 제가 담과 같은 script를 만들었습니다.

#!/bin/env bash
filename=compiled.dat
if [ -e $filename ];
then
    rm $filename
fi
for file in *N*.dat
do
    cat $file >> $filename
    echo "" >> $filename
done
echo "All files are concatenated."

이렇게 하면 compiled.dat란 파일이 만들어지지만, 파일 순서에 약간의 문제가 있습니다. 이렇게 하니까 다음의 순서로 파일들이 연결되었습니다.

 liftingline_div_N10.dat
 liftingline_div_N15.dat
 liftingline_div_N20.dat
 liftingline_div_N25.dat
 liftingline_div_N5.dat

근데, 저는 이 순서를 10, 15등등의 숫자 순서에 기반한 파일 순서대로 붙이고 싶습니다. 다음의 순서처럼요.

 liftingline_div_N5.dat
 liftingline_div_N10.dat
 liftingline_div_N15.dat
 liftingline_div_N20.dat
 liftingline_div_N25.dat

음.. 결국 파일 순서를 숫자에 기반해서 소팅해주는 부분이 필요하다는 것인데, sort를 이용해서 시도해 보았지만 잘 되지 않더군요. 이 부분을 어떻게 하면 해결 할 수 있을지 조언 좀 부탁드립니다.

익명 사용자의 이미지

이선중입니다.
아마도 이렇게 수정하면 원하는 결과를 낼 수 있을 것입니다.

#!/bin/env bash
filename=compiled.dat

if [ -e $filename ];
then
    rm $filename
fi

for i in $(ls | sed -e 's/liftingline_div_N\([0-9]*\)\.dat/\1/' | sort -n)
do
    echo liftingline_div_N${i}.dat
    cat  liftingline_div_N${i}.dat >> $filename
    echo "" >> $filename
done

echo "All files are concatenated."

물론 조금 더 생각하면 더 이쁘게도 만들 수 있겠지요.
예를 들면... liftingline_div_N 이나 .dat 같은 것을 변수로 한다던가...
(위의 코드로는 변수로 할 수 없습니다.)

aeronova wrote:
다음의 순서로 파일들이 연결되었습니다.

 liftingline_div_N10.dat
 liftingline_div_N15.dat
 liftingline_div_N20.dat
 liftingline_div_N25.dat
 liftingline_div_N5.dat

근데, 저는 이 순서를 10, 15등등의 숫자 순서에 기반한 파일 순서대로 붙이고 싶습니다. 다음의 순서처럼요.

 liftingline_div_N5.dat
 liftingline_div_N10.dat
 liftingline_div_N15.dat
 liftingline_div_N20.dat
 liftingline_div_N25.dat

익명 사용자의 이미지

조금 더 설명하는 것이 좋을 것 같습니다.

아이디어는 다음과 같습니다.

1. 숫자들을 정렬하고 싶다 ==> sort -n 을 사용한다
2. 문자열에서 숫자들을 뽑아내고 싶다 ==> sed 를 사용한다
문자열이 "문자부분숫자부분문자부분" 으로 구성되었다면 "[^0-9]*[0-9]*[^0-9]*"라는 정규표현식으로 나타낼 수 있습니다.
중간에 들어있는 숫자부분을 나중에 다시 사용하고 싶으면 \( 과 \) 로 둘러싸면 됩니다. 이것은 나중에 \1 로 다시 사용할 수 있습니다.
이렇게 되겠지요. "[^0-9]*\([0-9]*\)[^0-9]*"
이제 sed 에서 사용한 정규표현식이 이해가 갈 것입니다. s 명령을 사용하여 문자열 대치를 한 것입니다.
문자부분은 공백으로 대치되고 중간의 숫자부분만 남겨둡니다.
3. 실행 결과의 출력을 변수에 넣고 싶다 ==> $( 와 ) 사이에 명령을 쓴다
원래 사용하던 것은 bash 의 glob 대치 기능이였지만 이렇게 하지 않고 다른 출력 결과를 사용한 것입니다.

참고로...

FILE=liftingline_div_N10.dat
echo $FILE
FILE=${FILE#liftingline_div_N}
echo $FILE
FILE=${FILE%\.dat}
echo $FILE

도 한번 해보세요. 아주 bash 가 제공하는 재미있는 대치기능의 예입니다.

bash 는 강력한 쉘입니다. 저는 쉘 스크립트는 짜지 않습니다.
주로 그때 그때 명령으로 내려 사용합니다만... 여러가지 기능을 사용할 수 있지요...

익명 사용자의 이미지

이경우에는 더 간단하게도 할 수 있습니다.

파일이름들의 특성을 보니......
숫자가 나오기 전에는 반드시 N 이 등장하며 N 은 유일하게 한번만 등장합니다.
그렇다면 N 을 일종의 구분자로 사용할 수 있습니다.

#!/bin/env bash
filename=compiled.dat

if [ -e $filename ];
then
    rm $filename
fi

for i in $(ls | sort -n -tN +1)
do
    echo $i
    cat  $i >> $filename
    echo "" >> $filename
done

echo "All files are concatenated."

여기서는 sort 의 옵션만을 사용하기때문에 좀 더 쉽습니다.
앞에서 얘기한 것 처럼 -n 은 숫자로 생각하고 정렬하라는 의미입니다.
-tN 은 N 을 구분자로 사용하겠다는 것입니다. 만일 -t 옵션을 지정하지 않으면 빈칸(스페이스바를 누르는 것)을 구분자로 사용합니다.
+1 은 정렬할 때 처음의 키를 건너뛰고 정렬하겠다는 의미입니다.

aeronova의 이미지

친절한 설명 감사드립니다.
덕분에 bash를 사용하는 재미가 늘었네요. :)

It's better to burn out than to fade away. -- Kurt Cobain.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.