이 질문은 두 날짜(해당 날짜 포함 또는 제외) 사이의 텍스트를 찾는 경우를 제외하고 이전에 요청된 것입니다. 첫 번째 날짜를 선택하여 포함하고 두 번째 날짜는 제외하도록 답변 중 하나를 변경했습니다(생각/희망). 하지만 이것을 적용하려는 텍스트 파일을 어디에 제공하는지 이해가 되지 않습니다.
set - date1 date2 "junk"
from="$1"
till="$2"
file="$3"
# Output lines between two parameter dates
# INCLUDING the first parameter date but not the second
awk -v from=$from -v till=$till '
($2 >= from) && ($2 < till) { print $0 ; next }
($2 >= till) { exit }' "$file"
투박한 솔루션을 발견한 이후로 이를 개선하고 스크립트 줄에 작은 변경 사항을 여러 번 작성하는 것을 방지할 수 있는 또 다른 측면이 있다는 것을 깨달았습니다.
현재 작업 솔루션은 다음과 같습니다
awk '/^date_1_/,/^date_2_/ {print}' file.txt > file2.txt
grep -v "date_2_" file2.txt > file2tmp.txt
mv file2tmp.txt file2.txt
그래도 새로운 날짜마다 이 작업을 수행하고 싶습니다. 예를 들어 Date_1_(date_1_ 포함)부터 Date_2_(Date_2_ 제외)까지 텍스트를 선택한 다음 Date_2_부터 3까지 같은 방식으로 텍스트를 선택하고, 3~4(최대 1000)까지 같은 방법으로 선택합니다. 쉽게 확장할 수 있는 솔루션이 있습니까?
입력 텍스트 파일의 예(실제 파일은 최대 1000이고 txt 파일의 밑줄 사이에 공백이 없지만 기울임꼴 효과를 피하기 위한 백틱이 없습니다):
' > _ 1_ fe fi fo fum >_ 2_ beep bap bop >_ 3_ ti fi at at
출력 예:
텍스트 파일 1 생성됨: >_ 1_ fe fi fo fum
텍스트 파일 2 생성됨: >_ 2_ beep bap bop
텍스트 파일 3 생성됨: >_ 3_ ti fi at at
답변1
이 진화하는 질문의 현재 상태를 올바르게 이해한다면 임의 수의 줄이 있는 파일이 있고 to 와 같이 표시된 섹션으로 나누어져 있으며 _1_
해당 _1000_
섹션을 별도의 파일로 분할하고 싶을 것입니다. 그렇다면 csplit
다음과 같이 할 수 있습니다.
csplit file.txt '/^_[0-9]\+_/' '{*}'
답변2
이 awk
프로그램은 단일 명령으로 처음에 수행하려는 작업을 수행합니다.
awk '/^date_1_/,/^date_2_/ { if (prev) print prev ; prev=$0 }' file.txt > file2.txt
이것을 테스트했는데 작동합니다. 그런 다음 인수 쌍으로 제공된 일련의 일반 선 표시에 대해 연산을 수행할 수 있도록 문제를 확장합니다.
2가지 도우미 함수를 정의하여 이를 위한 편안한 작업 흐름을 만들 수 있습니다.
- 입력을 프로세스로 대체하는 awk 프로그램 만들기
- 다른 하나는 awk를 실행하여 첫 번째 도우미에게 인수를 전달합니다.
암호:
fun1(){ while [ ! -z $1 ] && [ ! -z $2 ] ; do echo "
/^$1/,/^$2/ {if (\$0~/^$1/) prev=\"\";
if (prev) print prev; prev=\$0 }"; shift; shift ; done }
fun2(){ awk -f <(fun1 $@); }
# Example data, example ranges, but could be any string:
seq 1 13 | sed -e 's/.*/_&_/' | fun2 _2 _4 _9 _11
_2_
_3_
_9_
_10_
문제 버전 3에 대한 해결책:
fun3(){ echo "/^$1/,/^$2/ {if (\$0~/^$1/) prev=\"\";
if (prev) print prev; prev=\$0 }"; }
fun4(){ ifile=$1; shift; while [ ! -z $1 ] && [ ! -z $2 ] ; do
awk -f <(fun3 $1 $2) $ifile > $1.txt ; shift; done }
# Create example data file:
seq 1 13 | sed -e 's/.*/_&_/' > inputData.txt
fun4 inputData.txt _2 _5 _8 _12
ls _*
_2.txt _5.txt _8.txt
답변3
나는 더 많은 책을 읽고 지금 나에게 맞는 것을 하나로 모았습니다.
awk '/^date_1_/,/^date_2_/ {print}' file.txt > file2.txt
grep -v "date_2_" file2.txt > file2tmp.txt
mv file2tmp.txt file2.txt
하지만 여전히 2단계와 임시 파일이 필요합니다.