foo.txt 파일이 있습니다
test
qwe
asd
xca
asdfarrf
sxcad
asdfa
sdca
dac
dacqa
ea
sdcv
asgfa
sdcv
ewq
qwe
a
df
fa
vas
fg
fasdf
eqw
qwe
aefawasd
adfae
asdfwe
asdf
era
fbn
tsgnjd
nuydid
hyhnydf
gby
asfga
dsg
eqw
qwe
rtargt
raga
adfgasgaa
asgarhsdtj
shyjuysy
sdgh
jstht
ewq
sdtjstsa
sdghysdmks
aadfbgns,
asfhytewat
bafg
q4t
qwe
asfdg5ab
fgshtsadtyh
wafbvg
nasfga
ghafg
ewq
qwe
afghta
asg56ang
adfg643
5aasdfgr5
asdfg
fdagh5t
ewq
별도의 파일 qwe
과 사이의 모든 줄을 인쇄하고 싶습니다. ewq
이것이 내가 지금까지 가지고 있는 것입니다:
#!/bin/bash
filename="foo.txt"
#While loop to read line by line
while read -r line
do
readLine=$line
#If the line starts with ST then echo the line
if [[ $readLine = qwe* ]] ; then
echo "$readLine"
read line
readLine=$line
if [[ $readLine = ewq* ]] ; then
echo "$readLine"
fi
fi
done < "$filename"
답변1
특정 순서 없이 스크립트를 일부 변경해야 합니다.
- 선행 및 후행 공백을 제거하지 않으려면
IFS=
before를 사용하세요 .read
- 어디에도 변화가 없기 때문에
$line
변수가 필요하지 않습니다readLine
. - 루프 중간에 읽기를 사용하지 마십시오! ! .
- 부울 변수를 사용하여 인쇄를 제어합니다.
- 인쇄의 시작과 끝을 지정합니다.
이러한 변경 후 스크립트는 다음과 같습니다.
#!/bin/bash
filename="foo.txt"
#While loop to read line by line
while IFS= read -r line; do
#If the line starts with ST then set var to yes.
if [[ $line == qwe* ]] ; then
printline="yes"
# Just t make each line start very clear, remove in use.
echo "----------------------->>"
fi
# If variable is yes, print the line.
if [[ $printline == "yes" ]] ; then
echo "$line"
fi
#If the line starts with ST then set var to no.
if [[ $line == ewq* ]] ; then
printline="no"
# Just to make each line end very clear, remove in use.
echo "----------------------------<<"
fi
done < "$filename"
다음과 같이 요약할 수 있습니다.
#!/bin/bash
filename="foo.txt"
while IFS= read -r line; do
[[ $line == qwe* ]] && printline="yes"
[[ $printline == "yes" ]] && echo "$line"
[[ $line == ewq* ]] && printline="no"
done < "$filename"
그러면 시작 줄과 끝 줄(포함)이 인쇄됩니다.
인쇄할 필요가 없으면 시작 및 종료 테스트를 바꿉니다.
#!/bin/bash
filename="foo.txt"
while IFS= read -r line; do
[[ $line == ewq* ]] && printline="no"
[[ $printline == "yes" ]] && echo "$line"
[[ $line == qwe* ]] && printline="yes"
done < "$filename"
readarray
그러나 배열 요소와 루프를 사용하는 것이 더 좋습니다(bash 버전 4.0 이상인 경우).
#!/bin/dash
filename="infile"
readarray -t lines < "$filename"
for line in "${lines[@]}"; do
[[ $line == ewq* ]] && printline="no"
[[ $printline == "yes" ]] && echo "$line"
[[ $line == qwe* ]] && printline="yes"
done
이렇게 하면 read
.
물론 sed
처리하려는 행만 가져오기 위해 권장(주석에서, 감사합니다, @costas) 줄을 사용할 수 있습니다.
#!/bin/bash
filename="foo.txt"
readarray -t lines <<< "$(sed -n '/^qwe.*/,/^ewq.*/p' "$filename")"
for line in "${lines[@]}"; do
: # Do all your additional processing here, with a clean input.
done
답변2
@Costas가 지적했듯이 작업에 적합한 도구는 다음과 같습니다 sed
.
sed '/qwe/,/ewq/ w other.file' foo.txt
인쇄할 라인에 대한 추가 처리가 필요할 수 있습니다. 괜찮습니다. 이렇게 하세요.
sed -e '/qwe/,/ewq/{w other.file' -e 'other processing;}' foo.txt
(물론 "다른 처리"는 실제 sed
명령이 아닙니다.) 위는 처리를 해야 할 경우 사용하는 패턴입니다.뒤쪽에라인을 인쇄합니다. 추가 처리를 수행한 다음 변경된 버전의 줄을 인쇄하려면(가능성이 더 높음) 다음을 사용할 수 있습니다.
sed -e '/qwe/,/ewq/{processing;w other.file' -e '}' foo.txt
(자체 매개변수에 넣어야 합니다 }
. 그렇지 않으면 이름의 일부로 해석됩니다 other.file
.)
귀하(OP)는 온라인에서 수행해야 하는 "추가 처리"가 무엇인지 명시하지 않았거나 더 구체적으로 설명할 수 있습니다. 그러나 처리가 무엇이든 확실히 거기에서 처리할 수 있습니다. 또는 이것이 너무 다루기 어려워지면 위의 코드를 거의 변경하지 않고 sed
처리 할 수 있습니다.awk
awk '/qwe/,/ewq/ { print > "other.file" }' foo.txt
그런 다음 프로그래밍 언어의 모든 기능을 사용하여 awk
명령문을 실행하기 전에 개별 줄을 처리 할 수 있습니다 print
. 물론입니다 awk
(그리고 sed
) 그렇습니다디자인됨텍스트 처리의 경우 bash
.
답변3
qwe(){ printf %s\\n "$1"; }
ewq(){ :; }
IFS= ### prep the loop, only IFS= once
while read -r in
do case $in in
(qwe|ewq)
set "$in"
;;
("$processing"?)
"$process"
esac
"$1" "$in"
done
이것은 매우 느린 방법입니다. GNU grep
와 일반infile
:
IFS=
while grep -xm1 qwe
do while read -r in &&
[ ewq != "$in" ]
do printf %s\\n "$in"
: some processing
done
done <infile
...비효율적인 읽기의 절반 이상을 최적화합니다...
sed -ne '/^qwe$/,/^ewq$/H;$!{/^qwe$/!d;}' \
-e "x;s/'"'/&\\&&/g;s/\n/'"' '/g" \
-e "s/\(.*\) .e.*/p '\1/p" <input |
sh -c 'p(){ printf %s\\n "$@"
for l do : process "$l"
done
}; . /dev/fd/0'
read
이렇게 하면 출력을 두 번 인쇄해야 하지만 대부분 sh
의 경우 비효율성을 피할 수 있습니다 . 한 번은 stdout에 대한 참조를 사용 sh
하고 한 번은 stdout에 대한 참조 없이 인쇄합니다. .
대부분의 구현에서 명령은 바이트가 아닌 청크로 입력을 읽는 것을 선호하기 때문에 다르게 작동합니다 . 그럼에도 불구하고 ewq - qwe를 완전히 제거하고 스트림 입력(예: FIFO)에서 작동합니다.
qwe
asd
xca
asdfarrf
sxcad
asdfa
sdca
dac
dacqa
ea
sdcv
asgfa
sdcv
qwe
a
df
fa
vas
fg
fasdf
qwe
aefawasd
adfae
asdfwe
asdf
era
fbn
tsgnjd
nuydid
hyhnydf
gby
asfga
dsg
qwe
rtargt
raga
adfgasgaa
asgarhsdtj
shyjuysy
sdgh
jstht
qwe
asfdg5ab
fgshtsadtyh
wafbvg
nasfga
ghafg
qwe
afghta
asg56ang
adfg643
5aasdfgr5
asdfg
fdagh5t
답변4
sed '/./=' input2.file | sed -n '/./N;s/\n/ /; /qwe/,/ewq/p'