for 루프에서 sed를 사용하여 여러 입력 파일 만들기

for 루프에서 sed를 사용하여 여러 입력 파일 만들기

값이 할당되지 않은 매개변수 "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...

  1. h편집 버퍼의 복사본으로 이전 버퍼를 덮어씁니다.
  2. gs///편집 버퍼에 있는 각 문자를 쉘 변수의 현재 값으로 전역적으로 대체합니다 .a$a
  3. 또한 p대체 결과를 s///표준 출력으로 인쇄하고 결과를 반복 가능 w파일 인 /tmp/$a.m곳에 기록합니다.$a
  4. 마지막으로 g편집 버퍼를 덮어써서 보유 버퍼를 설정합니다.

sed이 순서는 이름이 지정된 입력 파일의 각 줄에 적용됩니다. 처음 호출되면 이름이 지정된 각 write 파일을 자르지만 그런 다음 w각 rite 작업을 각 출력 파일에 순서대로 추가합니다. 하지만 한 줄만 있으므로 다음 i.msed같이 인쇄됩니다.

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

관련 정보