계산해서 파일에 쓰는 반복잡업 간단하게 할 수 있을까요

데이터 파일들이 여러개 있습니다.
예를들어 001.dat, 002.dat, …, 100.dat

각각 파일에서 필요한 값을 뽑아내기 위해 프로그램 실행파일(a.out) 하나 만들었습니다

계산한 값들을 result.dat 라는 파일에 저장하고 있습니다.

지금까지
$./a.out < 001.dat >> result.dat
$./a.out < 002.dat >> result.dat

$./a.out < 100.dat >> result.dat
이렇게 했는데,
아무리 생각해도 이건 아닌 것 같은데 간단한 방법이 없을까요.

이런 비슷한 작업들이 있는데 참고할 만한 것은 없을까요.

[quote="sj73ubuntu":15kicwo7]데이터 파일들이 여러개 있습니다.
예를들어 001.dat, 002.dat, …, 100.dat

각각 파일에서 필요한 값을 뽑아내기 위해 프로그램 실행파일(a.out) 하나 만들었습니다

계산한 값들을 result.dat 라는 파일에 저장하고 있습니다.

지금까지
$./a.out < 001.dat >> result.dat
$./a.out < 002.dat >> result.dat

$./a.out < 100.dat >> result.dat
이렇게 했는데,
아무리 생각해도 이건 아닌 것 같은데 간단한 방법이 없을까요.

이런 비슷한 작업들이 있는데 참고할 만한 것은 없을까요.[/quote:15kicwo7]

./a.out < NNN.dat >> result.dat 가 반복되는 것이면
숫자 들어가는 부분을 for나 while에 넣어서 돌리면 일일이 다 쓰지 않아도될 것 같습니다.

for i in ls -a1d *.dat|sort; do cat $i | a.out >> result.dat ; done

$./a.out < {001…100}.dat >> result.dat
???

$bash a < {001…100}.dat
$bash: {001…100}.dat: ambiguous redirect

그리고 원글 작성하신 분이 원하시는건
데이터파일 각각에 대해 a.out을 실행하는 것으로 보이는 군요

#케이스1
ls -a1d *.dat|sort|xargs -I{} a.out {} >> result.dat
#케이스2
for i in ls -a1d *.dat|sort; do cat $i | a.out >> result.dat; done

케이스1은 모든 데이터를 합쳐서 표준입력으로 연결시키고 a.out은 한번 호출
ls -a1d *.dat|sort|xargs cat|a.out >> result.dat과 같음

케이스2는 각각의 데이터에 파일에 대해 a.out호출 (여기선 100번)

[quote="protochaos":37uqra33]$bash a < {001…100}.dat
$bash: {001…100}.dat: ambiguous redirect

#케이스2
for i in ls -a1d *.dat|sort; do cat $i | a.out >> result.dat; done

케이스2는 각각의 데이터에 파일에 대해 a.out호출 (여기선 100번)[/quote:37uqra33]

제가 원하는 것이 케이스2입니다만
뭔가 잘 안되네요 "for i … ;done"을 명령창에 입력하는 건지요?

문장은 이상이 없는데요?
명령행에서 입력하는것인데…
경로를 따로 지정하지 않아 *.dat가 들어 있는 디렉토리에서 실행해야 되죠

for i in ls -a1d *.dat|sort; do cat "$i"| a.out >> result.dat; done

혹시 ls -ald로 하신게 아닐까요?
숫자1입니다.

헉 그러고 보니 *.dat에 result.dat도 포함되는군요.

for i in ls -a1d [0-9]*.dat|sort; do cat "$i"| a.out >> result.dat; done

이렇게 해야겠군요… 아니면 result.dat파일명을 바꾸시던가

또는

for i in {001…100}; do cat $i.dat | a.out >>result.dat; done

[quote="protochaos":33254rc0]문장은 이상이 없는데요?
명령행에서 입력하는것인데…
경로를 따로 지정하지 않아 *.dat가 들어 있는 디렉토리에서 실행해야 되죠

for i in ls -a1d *.dat|sort; do cat "$i"| a.out >> result.dat; done

혹시 ls -ald로 하신게 아닐까요?
숫자1입니다.

헉 그러고 보니 *.dat에 result.dat도 포함되는군요.

for i in ls -a1d [0-9]*.dat|sort; do cat "$i"| a.out >> result.dat; done

이렇게 해야겠군요… 아니면 result.dat파일명을 바꾸시던가

또는

for i in {001…100}; do cat $i.dat | a.out >>result.dat; done[/quote:33254rc0]

여러번 답변해 주셔서 감사합니다만
역시 전 안되는군요.
답변보고 쉘스크립트라는 걸 뒤져보다
for i in 'ls -a1d *.dat|sort’가 .dat로 끝나는 파일을 정열해서 i에 기억? 하는정도까지는 감이 오는데 그 뒤는 잘 모르겠습니다.
$./a.out < 001.dat >> result.dat
로 했는데 위 스크립트에서 < 001.dat 부분이 빠진건 아닌지 모르겠습니다.

뭔가 참고 할 만한 자료라도 있으면 좋겠는데 뭘 봐야되는지도 잘 모르는 수준이라
암튼 감사드립니다.

작은 따옴표가 아닙니다.
~밑의 글쇠인 입니다. 이게 잘 못 하신듯하네요..ls -a1d[0-9].dat` == $(ls -a1d[0-9].dat) 와 같이 표현할 수 도 있습니다.

for i in ls -a1d [0-9]*.dat|sort; do cat "$i"| a.out >> result.dat; done

for 변수 in 집합;
do

done

집합은 스페이스와 줄바꿈으로 구분되구요
A=명령 : 명령을 실행하고 그 결과를 A에 저장

ls의 -a 는 숨김파일까지 전부 -1은 파일명만 -d는 일치하는 파일만(서브디렉토리 검색안함)
[0-9]*는 정규표현식으로 숫자가 앞에 있는 파일명을 뜻하구
sort는 번호순으로 정렬

cat은 해당파일의 내용을 표준출력스트림으로 출력

[quote="protochaos":3si64i6b]작은 따옴표가 아닙니다.
~밑의 글쇠인 입니다. 이게 잘 못 하신듯하네요..ls -a1d[0-9].dat` == $(ls -a1d[0-9].dat) 와 같이 표현할 수 도 있습니다.

for i in ls -a1d [0-9]*.dat|sort; do cat "$i"| a.out >> result.dat; done

for 변수 in 집합;
do

done

집합은 스페이스와 줄바꿈으로 구분되구요
A=명령 : 명령을 실행하고 그 결과를 A에 저장

ls의 -a 는 숨김파일까지 전부 -1은 파일명만 -d는 일치하는 파일만(서브디렉토리 검색안함)
[0-9]*는 정규표현식으로 숫자가 앞에 있는 파일명을 뜻하구
sort는 번호순으로 정렬

cat은 해당파일의 내용을 표준출력스트림으로 출력[/quote:3si64i6b]

이 부분을 제가 잘못 입력한게 맞습니다. for i inls -a1d [0-9]*.dat|sort`; do cat "$i" >> result.dat; done
이렇게 해보니 모든 파일들이 result.dat에 저장이 되는군요. 설명을 보니 여기까진 알 것 같습니다.
다만 a.out은 파일 하나씩 받아들여 결과값을 출력해주는데 아무래도 이부분은 이해가 안되는군요.
cat "$i"| a.out 이 것이 a.out이 파일 i번째 내용을 받아 들여 계산하여 결과를 출력한다는 뜻인가요
혹시나 해서(또 스크립트를 잘 몰라서) do ./a.out < cat "$i" >> result.dat; done 라고 했는데 역시 안됩니다.
그리고 | 이건 또 무슨 의미인지요 검색을 해보려고해도 이름을 알 수 없어서요.

http://www.joinc.co.kr/modules/moniwiki … index.html
screenshot80.png

헉 파이프를 모르시다니 ㅠ.ㅠ

DOS에서도 type a.txt | more 이런거 안해보셨나요?

파이프라는것은 파이프가 양쪽에 통로가 있고 이쪽에서 집어넣으면 저쪽에서 나오는거죠

먼저 스트림이라는 것을 알아야 해요.
스트림(stream)이라는 것은 흐름이란 뜻인데…
컴퓨터 용어로는 입출력 가상 장치를 말하는 것이고,
표준 스트림은
표준입력스트림(stdin:보통 키보드), 표준출력스트림(stdout:보통 화면), 표준에러스트림(stderr:에러출력 화면)
이 있구요. 그밖에도 파일입력스트림, 파일출력스트림등등이 있죠.
이 스트림들간에는 연결이 가능하죠
표준출력 -> 표준입력 ->표준에러->표준입력->파일
머 이런 식으로 이 일련의 과정이 흐름과도 같은 것이죠

A라는 프로그램이 표준출력(stdout:보통 화면)으로 출력하는 기능이 있고,
B라는 프로그램이 표준입력(stdin:보통 키보드)에서 읽어서 저장하는 기능이 있을 경우

A라는 프로그램의 결과를 result.dat로 저장한다면
A > result.dat 라고 하면 되죠 > 기호는 이때 재지향(Redirection)이라고 하죠
재지향은 파일이거나 표준스트림일 경우에 사용하는 경우이고요
do ./a.out < cat "$i" >> result.dat 이문장의 오류는
cat "$i"라는 파일을 찾으려고 하니 안되는 겁니다.
제대로 된 문장으로 바꾼다면 do ./a.out < "$i" >> result.dat 처럼 써야 하죠.

A명령 > result.dat > B명령 과 같이 연결하고 싶을 경우 가 많겠지요?
이럴 경우 result.dat 라는 임시파일은 필요없고,
바로 A | B라고 한다면, A 명령의 결과가 B 명령의 표준입력으로 처리됩니다.
A라는 프로그램의 기능이
printf("%s", "hahaha")요런 식이라면
B라는 프로그램은
scanf("%s", &s) 요런식으로 읽어 들이게 되고,
s에는 hahaha라는 값이 저장되죠

| 기호는 \글쇠의 윗글자인데 잘 보시면 막대기에 구멍이 뚫린 형태입니다.
그 구멍으로 데이터가 오간다는 모양으로 그 기호를 파이프로 사용합니다.

more라는 프로그램은 표준 입력에서 데이터를 읽어들여
표준 출력인 화면에 출력하는데 화면이 꽉차면, 더이상 출력하지 않고 키입력을 기다리죠

그래서 유닉스계열 도움말(manual) 명령인 man의 경우
man ls|more
하면 화면단위로 ls의 도움말을 볼 수 있는거죠.

이경우 man ls라는 명령에 오류가 생긴다면 그결과는 표준 오류에 출력되구요
|more에 의해 파이핑된 데이터에는 이 오류메시지가 포함되지 않습니다.
그래서 more의 영향없이 오류는 주주룩 출력되죠

이경우 오류도 화면 단위로 끊어 보려면
man ls 2>&1 |more
2는 표준 에러구요, 1은 표준출력입니다.
>& 연산자는 스트림간의 재지향을 나타냅니다.
2번(표준에러)스트림을 1번(표준 출력)스트림으로 연결하게 되서
more라는 프로그램에선 오류까지도 표준입력으로 읽어 들이게 되죠.

[code:38bmkllb]
$./a.out < 001.dat >> result.dat
$./a.out < 002.dat >> result.dat
...
$./a.out < 100.dat >> result.dat
[/code:38bmkllb]
이것이 원본 방법이었는데…

[code:38bmkllb]
for i in ls -a1d &#91;0-9&#93;*&#46;dat|sort; do cat "$i"| a.out >> result.dat; done
[/code:38bmkllb]

잠깐 궁금한데요…구지 저기에 cat 을 쓸 이유가 있었나요?
첫 부분 그대로 a.out < 002.dat >> result.dat 해도 같은 결과가 나오지 않을까요?

[code:38bmkllb]
for i in seq -f %03g 1 100;do ./a.out < $i.dat >> result.dat;done
[/code:38bmkllb]
저는 이렇게 주로 사용하는줄 알았는데…cat 을 쓰면 파이프 입력보다 수행 속도가 더 빠른가 ?..궁금하군요.