2017-10-17 1 views
0

sed으로 수행하려는 대체 목록이 있습니다. 치환을 하나의 sed 명령으로 결합하는 대신, 나는 bash 루프의 반복에서 각 치환을 수행하고 싶다. 예를 들면 다음과 같습니다.다음 반복으로 bash 루프 반복 출력

cat ${input} | 
for subst in "${substlist}"; do 
    sed 's/'${subst}'/modified_'${subst}'/g' 
done > ${output} 

각 반복마다 전체 스트림을 수정하지만 첫 번째 반복이 입력을받는 것으로 볼 수 있습니다.

이 패턴은 bash에서 가능합니까?

+0

BTW,'$는 {substlist은}'문자열을 확대 - 일반적으로 말하자면 따옴표 붙이지 않은 확장을 통해 단어 분할에 의존하는 것이 아니라 적절한 배열을 사용해야합니다. 즉, 가장 좋은 방법은'substlist = ("first" "second" "third"); "$ {substlist [@]}"의 subst에 대한; do ... ... ' –

+1

왜 그것들을 하나의'sed' 명령으로 결합하고 싶지 않으십니까? 그것이 몇 가지 대답입니다. – Barmar

+0

BTW, 다른 모든'sed' 프로세스 (모든 이상한 이유로)에서 모든 치환을 한꺼번에 (즉, 동시에) 실행하려면 그 중 가장 적합한 '반복'의 종류는 재귀 함수 대 bash 'for' 루프. 예 :'multised() {case $ # 0) cat ;; 1) sed -e "$ 1";; *) local cur = $ 1; 시프트; sed -e "$ cur"| multised "$ @";; esac; }'배열로'substs'를 가지고 있다면'multised "$ {substs [@]}"<"$input" > "$ output"로 사용할 수 있습니다. –

답변

-1

입력 파일을 출력 파일에 복사 한 다음 -i 옵션을 사용하여 대체 파일을 덮어 쓰려면 sed을 수행하십시오. BSD와

cp "$input" "$output" 
for subst in $substlist 
do 
    sed -i "s/$subst/modified_$subst/g" "$output" 
done 

는/필요 OSX sed가되게합니다 :

sed -i '' "s/$subst/modified_$subst/g" "$output" 
+0

여분의 복사 작업이 가능하고 이식성이 좋습니다 (BSD sed의 버전'-i'에서는 작동하지 않습니다). –

+0

@CharlesDuffy 그들은 한 개의'sed' 명령으로 그것을하고 싶지 않다고 말했다. – Barmar

+0

아. 나는 ... 관심이있을 것이다 ... 실제 문제가 있는지 (XY 문제인지 - 즉, 루프가 인수 목록을 작성하는 데 사용될 수 있다는 것을 알지 못함) 공정한 것이지. –

0

여기 단일 스트림으로 할 수있는 한 가지 방법입니다. ${substlist}에서 나오지 인수를 구축하고 나오지도 한 번 전화 :

#!/bin/sh 

cat ${input} | 
sed `for subst in ${substlist}; do 
     echo " -e s/${subst}/modified_${subst}/g " 
    done` > ${output} 

${substlist}에 당신이 추가 이스케이프 할 필요가 있습니다에 따라.

+0

영업 사원이 이미 인용 부호가없는 확장을 한 번 실행하고있는 것은 좋지 않습니다. 그것으로부터의 출력의 인용되지 않은 확장 *을하는 것은 무의미한 실패 사례를 더 추가하는 것입니다. (또한 bash의'echo'가 POSIX 스펙을 따르지 않기 때문에,'-e'는'sed'가 리터럴'-e' 인수를 넘기지 않고 어떻게 동작 하는지를 수정합니다. 그 결과는 다음과 같습니다. 치환을 제외한 모든 것은'sed '에 의해 수행 할 연산이 아니라 입력 파일 이름으로 취급 될 것입니다. –

+0

우수한 점. –

+0

@CharlesDuffy #!를 나타 내기 위해 편집 됨!/ bin/sh하지만 에코와의 이식성 문제로 인해 빈약 한 해결책이된다는 데 동의합니다. –

1

sed에 전달할 -e 옵션의 배열을 만듭니다.

filters=() 
for subst in ${substlist}; do 
    filters+=(-e "s/$subst/modified_$subst/") 
done 
sed "${filters[@]}" "$input" > "$output" 

는 (. 인용되지 않은 매개 변수 확장 반복하고 동적으로 각 sed 필터를 만드는 문제는이 답변의 범위를 벗어납니다)

관련 문제