값이 할당되지 않은 매개변수 "a"를 포함하는 "am"이라는 간단한 Mathematica 스크립트 파일이 있다고 가정해 보겠습니다.
Solve[x^2+5^a==0,x]>>a.out
내가 원하는 것은 "a" 값을 1에서 10으로 변경하여 여러 스크립트 파일을 만들고 1.m, 2.m 등과 같이 해당 "a" 값으로 각 파일의 이름을 지정하는 것입니다. 이를 위해 다음과 같이 for 루프에서 'sed' 명령을 사용해 보았습니다.
for ((i=1; i<=10; i++)); do sed 's/a/i/' <a.m >i.m; done
이렇게 하면 i의 각 고정 값에 대해 "a"가 숫자 값으로 바뀌고 "im"이라는 새 파일이 생성됩니다. 그러나 위 줄은 im이라는 단일 스크립트 파일을 생성합니다. 여기서 "a"는 "i"로 대체됩니다. 어떤 제안이 있으십니까?
답변1
쉘 스크립트에는 많은 리터럴 문자열(명령 이름, 파일 이름 등)이 포함되어 있으므로 변수 값을 사용하려면 이를 변수 참조로 명시적으로 표시하는 문자가 필요합니다.매개변수 확장$
그 뒤에 변수 이름이 옵니다(가장 간단한 형식).일반적으로 변수 대체에는 큰따옴표가 필요합니다.. 작은따옴표 내에서 변수는 전혀 확장되지 않습니다( $
내부적으로는 '…'
그 자체만 나타냄). 그러므로:
for ((i=1; i<=10; i++)); do
sed "s/a/$i/" <a.m >"$i.m"
done
이중 괄호 안에는 이중 괄호가 산술 표현식을 구분하고, 산술 표현식에는 문자열이 없으므로 단순 단어는 역참조할 변수로 해석되므로 달러 기호가 필요하지 않습니다.
sed 명령은 a
템플릿 파일의 첫 번째 문자를 대체합니다. 다른 이름(예: 함수 이름)에는 표시되지 않는 변수 이름을 선택할 수 있습니다. 또는 스크립트 시작 부분에서 할당을 생성할 수 있습니다.
for ((i=1; i<=10; i++)); do
echo "a=$i;" >"$i.m"
cat a.m >>"$i.m"
done
답변2
sed
하나만 호출할 수 있는데 너무 많은 s를 호출하는 것은 잘못된 것 같아요. sed
입력을 효과적으로 반복하고 이를 다른 출력으로 수정하는 기능으로 유명합니다.많은 종류의내보내기도 매우 쉽습니다. 예를 들어, 여기 POSIX 휴대용이 있습니다.(그리고 더 효율적)루프 를 다시 작성하십시오 for
.
echo "Solve[x^2+5^a==$((a=0)),x]>>a.out" >/tmp/i.m ###create file + init $a
until [ "$((a+=1))" -gt 10 ] ###iterate + test
do printf "h;s/a/$a/gpw /tmp/$a.m\ng;" ###push new sed command
done| sed -nf - /tmp/i.m ###read + apply commands
head /tmp/[0-9].m /tmp/10.m ###print results
sed
해당 스크립트는 stdin에서 읽을 수 있고 명명된 파일에 적용할 수 있습니다. 이것이 바로 sed -nf - /tmp/i.m
위 명령문이 수행하는 작업입니다. 동시에 p
출력을 표준 출력으로 인쇄 할 수도 있습니다.그리고 w
하나 이상의 명명된 파일에 출력을 씁니다. 쉘 루프가 작동하면 행을 인쇄 sed
하고 완료되면 총계는 다음과 같습니다.
h;s/a/1/gpw /tmp/1.m
g;h;s/a/2/gpw /tmp/2.m
g;h;s/a/3/gpw /tmp/3.m
g;h;s/a/4/gpw /tmp/4.m
g;h;s/a/5/gpw /tmp/5.m
g;h;s/a/6/gpw /tmp/6.m
g;h;s/a/7/gpw /tmp/7.m
g;h;s/a/8/gpw /tmp/8.m
g;h;s/a/9/gpw /tmp/9.m
g;h;s/a/10/gpw /tmp/10.m
g
이것은 말해줍니다 sed
...
h
편집 버퍼의 복사본으로 이전 버퍼를 덮어씁니다.g
s///
편집 버퍼에 있는 각 문자를 쉘 변수의 현재 값으로 전역적으로 대체합니다 .a
$a
- 또한
p
대체 결과를s///
표준 출력으로 인쇄하고 결과를 반복 가능w
파일 인/tmp/$a.m
곳에 기록합니다.$a
- 마지막으로
g
편집 버퍼를 덮어써서 보유 버퍼를 설정합니다.
sed
이 순서는 이름이 지정된 입력 파일의 각 줄에 적용됩니다. 처음 호출되면 이름이 지정된 각 w
rite 파일을 자르지만 그런 다음 w
각 rite 작업을 각 출력 파일에 순서대로 추가합니다. 하지만 한 줄만 있으므로 다음 i.m
과 sed
같이 인쇄됩니다.
Solve[x^2+5^1==0,x]>>1.out
Solve[x^2+5^2==0,x]>>2.out
Solve[x^2+5^3==0,x]>>3.out
Solve[x^2+5^4==0,x]>>4.out
Solve[x^2+5^5==0,x]>>5.out
Solve[x^2+5^6==0,x]>>6.out
Solve[x^2+5^7==0,x]>>7.out
Solve[x^2+5^8==0,x]>>8.out
Solve[x^2+5^9==0,x]>>9.out
Solve[x^2+5^10==0,x]>>10.out
그리고 head
새로 생성된 10개의 파일 각각을 읽고 /tmp
다음을 인쇄합니다.
==> /tmp/1.m <==
Solve[x^2+5^1==0,x]>>1.out
==> /tmp/2.m <==
Solve[x^2+5^2==0,x]>>2.out
==> /tmp/3.m <==
Solve[x^2+5^3==0,x]>>3.out
==> /tmp/4.m <==
Solve[x^2+5^4==0,x]>>4.out
==> /tmp/5.m <==
Solve[x^2+5^5==0,x]>>5.out
==> /tmp/6.m <==
Solve[x^2+5^6==0,x]>>6.out
==> /tmp/7.m <==
Solve[x^2+5^7==0,x]>>7.out
==> /tmp/8.m <==
Solve[x^2+5^8==0,x]>>8.out
==> /tmp/9.m <==
Solve[x^2+5^9==0,x]>>9.out
==> /tmp/10.m <==
Solve[x^2+5^10==0,x]>>10.out