[완료]쉘스크립트로 행렬의 빈 곳을 특정문자로 채우는 방법?

foruses의 이미지

쉘 스크립트를 사용하여 아래와 같이 행렬에서 빈 컬럼의 뒷부분을 특정 문자(가령 N)로 채우고 싶은데 어떤 방법이 좋을까요?
(각 컬럼은 스페이스로 구분되어 있는 경우입니다.)

변형 전
2 1 5 4 5
4 8 9 4
1 5 1
1 4 2 5 5 8

변형 후
2 1 5 4 5 N
4 8 9 4 N N
1 5 1 N N N
1 4 2 5 5 8

ymir의 이미지

한 줄 씩 읽어서 빈 컬럼에 채워넣어야 할 것 같긴 한데..
그냥 간단히 결과만 나오게 해보자면..;;

$ cat matrix.in
2 1 5 4 5
4 8 9 4
1 5 1
1 4 2 5 5 8
$ cat matrix.in | sed 's/$/ n n n n n n n n n n/g' | cut -d' ' -f-6
2 1 5 4 5 n
4 8 9 4 n n
1 5 1 n n n
1 4 2 5 5 8

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

foruses의 이미지

제가 하려는 작업의 행렬 사이즈가 "수백x수천"이라서요, 효율적인 방법이 없을까요?
포트란을 사용하기 전에 왠만하면 command line에서 해결하고 싶은 생각에서요.

ymir의 이미지

어떤 면에서 '효율'적이어야 하는지요..?
어차피 컬럼 개수 세어서 모자란 개수 만큼 뿌려줘야 하는건 크게 달라지지 않을텐데요.

#!/bin/bash
 
maxcols=6
 
while read -r line; do
        ncol=$(wc -w <<< $line)
        echo -n $line
 
        let nleft=maxcols-ncol
        until [ $nleft -eq 0 ] ; do
                echo -n " n"
                let nleft--
        done
        echo ""
done < matrix.in

먼저 올린 방식에서도, 채워야 할 문자열은 간단히 명령 한 줄로 만들 수 있습니다.

$ rep=$(yes " n" | head -n 6 | tr -d '\n')
$ echo "$rep"
 n n n n n n

그 담에 그냥 처음 올렸던 방식대로 하시거나..
위처럼 몇 가지 조건문을 달아서 정교하게 처리하시거나.. 원하시는 대로..

아.. 그리고 아시겠지만 위 방식들은 행렬의 중간이 비어 있는 상황에서는 쓸 수 없습니다.
그것 먼저 확인했어야 했는데 그냥 깜빡했네요.

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

foruses의 이미지

상세한 설명 다시 한번 감사합니다. ^^

그런데 제가 기초지식이 부족해서 활용에 어려움이 있네요.

cat matrix.in | sed 's/$/ n n n n n n n n n n/g' | cut -d' ' -f-6 에서 말씀하신대로 n의 개수를 임의로 변경할 때, rep=$(yes " n" | head -n 6 | tr -d '\n') 는 어떻게 결합해야 하는지요.

반복되는 질문이라 민망하지만, 염치불구하고 다시 문의드립니다. 꾸벅.

ymir의 이미지

sed 에 변수 넣으면서 작은 따옴표 대신 큰 따옴표로 바꾼 것에 주의하세요.

$ maxcol=20
$ rep=$(yes " n" | head -n $maxcol | tr -d '\n')
$ cat matrix.in | sed "s/$/$rep/g" | cut -d' ' -f-$maxcol
2 1 5 4 5 n n n n n n n n n n n n n n n
4 8 9 4 n n n n n n n n n n n n n n n n
1 5 1 n n n n n n n n n n n n n n n n n
1 4 2 5 5 8 n n n n n n n n n n n n n n

참고로, 최대 컬럼 개수는 다음과 같이 array 에 넣어서 계산해도 됩니다.

$ maxcol=0
$ while read -a arr; do [ ${#arr[@]} -gt $maxcol ] && maxcol=${#arr[@]}; done < matrix.in
$ echo $maxcol
6

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

ymir의 이미지

글고 보니.. array 쓰면 두 번째 올렸던 스크립트도 좀 더 간단히 줄일 수 있겠네요.

$ maxcol=6
$ while read -a arr; do echo -n ${arr[@]}; for ((i=${#arr[@]}; i<$maxcol; i++)); do echo -n " n"; done; echo ""; done < matrix.in
2 1 5 4 5 n
4 8 9 4 n n
1 5 1 n n n
1 4 2 5 5 8
$ maxcol=20
$ while read -a arr; do echo -n ${arr[@]}; for ((i=${#arr[@]}; i<$maxcol; i++)); do echo -n " n"; done; echo ""; done < matrix.in
2 1 5 4 5 n n n n n n n n n n n n n n n
4 8 9 4 n n n n n n n n n n n n n n n n
1 5 1 n n n n n n n n n n n n n n n n n
1 4 2 5 5 8 n n n n n n n n n n n n n n

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

익명 사용자의 이미지

cat matrix.in | awk '{printf $0 ; for (i = NF; i < 100; i++) printf " N"; printf "\n"}'
익명 사용자의 이미지

$ cat append.sh
#!/bin/bash
if [ $# -ne 2 ]; then
    >&2 echo "Usage: $0 in.txt out.txt"
    exit
fi
N=$(awk 'BEGIN{n=0}{if(NF>n)n=NF;}END{print n}' $1)
awk -v N=$N '{printf $0 ; for (i = NF; i < N; i++) printf " N"; printf "\n"}' $1 > $2
 
$ bash append.sh matrix.in matrix.out
bushi의 이미지

$ suffix="n n n n n n n n"
 
$ while read x; do echo "$x $suffix" | cut -d ' ' -f-6; done < matrix.in 
2 1 5 4 5 n
4 8 9 4 n n
1 5 1 n n n
1 4 2 5 5 8

효율적으로 하려면

$ while read x; do echo "$x $suffix"; done < matrix.in | cut -d ' ' -f-6
2 1 5 4 5 n
4 8 9 4 n n
1 5 1 n n n
1 4 2 5 5 8

20개의 column 을 가진 suffix template 을 만드려면

$ suffix=$(for i in $(seq 1 1 20);do echo " n"; done)
$ echo $suffix
n n n n n n n n n n n n n n n n n n n n

foruses의 이미지

덕분에 문제는 해결되었습니다.
완전한 이해는 여전히 어렵지만 열심히 들여다보면서 익히는 중입니다....갈 길이 머네요 ㅎㅎ

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.