예를 들어 file.txt의 유일한 콘텐츠는 다음과 같습니다.
xxxxxxxxxHAHAxxxxxxHOHOxxxxxxx
HAHA를 seq 1 3으로 바꾸고 HOHO를 seq 5 7로 바꾸고 싶으므로 출력은 다음과 같아야 합니다.
xxxxxxxxx1xxxxxx5xxxxxxx
xxxxxxxxx2xxxxxx6xxxxxxx
xxxxxxxxx3xxxxxx7xxxxxxx
내가 뭘 한거지:
for i in $(seq 1 3)
do sed "s/HAHA/$i/g" file.txt
for i in $(seq 5 7)
do sed "s/HOHO/$i/g" file.txt
done
done > new.txt
하지만 new.txt는 내가 기대한 것을 표시하지 않습니다. 코드를 어떻게 변경해야 하나요?
답변1
bash
내장 명령을 사용하여 read
다양한 파일 설명자의 기능을 읽는 방법은 다음과 같습니다 .
while read -u3 i && read -u4 j; do
sed -e "s/HAHA/$i/" -e "s/HOHO/$j/" file.txt
done > new.txt 3< <(seq 1 3) 4< <(seq 5 7)
seq
숫자에는 간단한 산술 관계가 있으므로 단일 프로세스 + 일부 쉘 산술을 사용하는 것이 더 간단합니다.
for i in $(seq 1 3); do
sed -e "s/HAHA/$i/" -e "s/HOHO/$((i+4))/" file.txt
done > new.txt
두 경우 모두 다음을 참조하세요.쉘 루프를 사용하여 텍스트를 처리하는 것이 왜 나쁜 습관으로 간주됩니까?- 제공한 최소한의 예에서는 비효율성이 중요하지 않을 수 있지만 더 심각한 작업을 수행하는 경우 다른 접근 방식을 사용하는 것을 고려해야 합니다.
답변2
생성된 각 행에 대해 외부 유틸리티를 호출할 필요가 없습니다.
read template <file
paste <(seq 1 3) <(seq 5 7) |
while read x y; do
t=${template/HAHA/$x}
t=${t/HOHO/$y}
printf '%s\n' "$t"
done >new.txt
file
이것은 먼저 이름이 into 인 파일에서 행을 읽습니다 $template
. 그런 다음 루프에 대한 2열 입력을 구성합니다 while read
. 루프에 대한 입력은 의 숫자로 구성된 두 열입니다 seq
.
루프 내에서 의 bash
값에 대해 특정 대체를 수행하여 $template
및 문자열을 읽은 숫자로 바꿉니다. 그러면 생성된 후 출력됩니다.HAHA
HOHO
paste
$t
를 사용 awk
하고 입력이 단 한 줄이라고 가정합니다.
awk '{
for (i = 1; i <= 3; ++i) {
t = $0;
sub("HAHA", i, t)
sub("HOHO", 4+i, t)
print t
}
}' file
위의 코드를 bash
모방한 for loop 쉘 :awk
read template <file
for (( i = 1; i <= 3; ++i )); do
t=${template/HAHA/$i}
t=${t/HOHO/$((i+4))}
printf '%s\n' "$t"
done