IFS=$'?\n'
for line in $(cat "./newfiletoread")
do printf "${line}\n"
done
파일 내용은 다음과 같습니다. 안녕하세요! 괜찮으세요? 인생은 어때요? 내 인생은 겨울 아침만큼 지루합니다!
위의 코드는 '?' 또는 '!'를 발견하면 파일의 내용을 분할합니다. ' 또는 '/n'이면 괜찮습니다. 그러나 확장 중에 쉘은 파일에서 이러한 문자를 제거합니다. 아래는 내가 얻은 결과입니다.
Hello there
How are you doing
How is life
Mine is as boring as a winter morning
명령이 실행되기 전에 이러한 IFS 값을 공백으로 바꾸면 쉘이 작동한다는 것을 알고 있습니다. 분할하는 동안 이러한 구분 기호를 유지하는 방법이 있습니까? 아래와 같은 출력을 얻고 싶습니다.
Hello there!
How are you doing?
How is life?
Mine is as boring as a winter morning!
답변1
첫 번째,파일에서 줄을 읽지 마세요for
문자열 분할에 대해 어딘가에서 읽었습니다. split
무엇을 버려야 할지 알 때 사용하고, 무엇을 유지해야 할지 알 때 정규식을 사용하십시오. 또는 그런 것.
쉘 단어 분할을 사용할 때의 문제점 $IFS
은 해당 변수의 모든 문자가 분할에 사용되며 어느 문자인지 알 수 없다는 것입니다.
Bash를 사용하면 다음과 같이 작성할 수 있습니다.
line='Hello there! How are you doing? How is life? Mine is as boring as a winter morning!'
line=${line//\?/$'"?\n'}
line=${line//\!/$'"!\n'}
echo "$line"
Hello there"!
How are you doing"?
How is life"?
Mine is as boring as a winter morning"!
선행 공백에 유의하십시오. 이는 보다 복잡한 패턴으로 해결할 수 있습니다.line=${line//\?*([[:blank:]])/$'"?\n'}
나는 다음을 사용할 것이다 sed
:
line='Hello there! How are you doing? How is life? Mine is as boring as a winter morning!'
new=$( sed 's/[?!][[:blank:]]*/&\n/g' <<<"$line" )
echo "$new"
Hello there!
How are you doing?
How is life?
Mine is as boring as a winter morning!
앗split()
구분 기호를 캡처할 수 있는 기능이 있지만 이를 사용하는 것은 매우 장황합니다.
echo "$line" | awk '{
n = split($0, words, /[!?][[:blank:]]*/, seps)
for (i = 1; i < n; i++)
print words[i] seps[i]
print words[n]}
'