Linhas de saída entre duas datas de parâmetros INCLUINDO a data do primeiro parâmetro, mas não a segunda

1

Estas perguntas foram feitas antes, exceto que estavam procurando texto entre duas datas, incluindo ou excluindo essas datas. Eu mudei uma das respostas para que ela selecionasse e incluísse desde a primeira data e acessasse, mas excluísse a segunda data (eu acho / espero). No entanto, não entendo onde você fornece o arquivo de texto no qual deseja aplicar isso?

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"

Desde que descobri uma solução clumpy, percebi que há outro aspecto que melhoraria isso e me impediria de ter que fazer pequenas alterações na linha do script muitas vezes.

A solução de trabalho atual é:

awk '/^date_1_/,/^date_2_/ {print}' file.txt > file2.txt
grep -v "date_2_" file2.txt > file2tmp.txt
mv file2tmp.txt file2.txt

No entanto, gostaria que fizesse isso para cada nova data. por exemplo. selecione o texto de Date_1_ (incluindo date_1_) até, mas não incluindo Date_2_, depois selecione o texto de Date_2_ para 3 da mesma forma, de 3 a 4 da mesma maneira (até 1000). Existe uma solução que eu possa ampliar facilmente?

Exemplo de arquivo de texto de entrada (embora o arquivo real suba para 1000, também não há espaços entre os sublinhados no arquivo txt, mas eu não tenho um caractere de retorno para escapar dos efeitos itálicos):

'> _ 1_ fe fi fo fum > _ 2_ bip bop bop > _ 3_ ti fi at às

Exemplo de saída:
arquivo de texto criado file1: > _ 1_ fe fi fo fum
arquivo de texto criado 2: > _ 2_ beep bap bop
arquivo de texto criado3: > _ 3_ ti fi at at

    
por Giles 11.07.2016 / 15:33

3 respostas

2

Se eu entendi o estado atual dessa questão em constante movimento corretamente, você tem um arquivo com um número arbitrário de linhas, dividido em seções marcadas por algo como _1_ to _1000_ , e você gostaria de dividir essas seções em arquivos individuais. Se sim, então csplit pode fazer isso:

 csplit file.txt '/^_[0-9]\+_/' '{*}'
    
por 12.07.2016 / 08:10
2

Este programa awk realizará o que você queria fazer primeiro em um comando:

awk '/^date_1_/,/^date_2_/ { if (prev) print prev ; prev=$0 }' file.txt > file2.txt

Você testou isso e funcionou. Então você estendeu a questão para poder operar em um intervalo de marcadores de linha genéricos dados como pares de argumentos.

Você pode criar um fluxo de trabalho confortável definindo 2 funções auxiliares:

  • Um cria o programa awk para alimentar através da substituição do processo
  • O outro executa o awk com os parâmetros enviados ao primeiro ajudante:

Código:

fun1(){ while [ ! -z $1 ] && [ ! -z $2 ] ; do echo "
/^$1/,/^$2/ {if (\
fun3(){ echo "/^$1/,/^$2/ {if (\
fun1(){ while [ ! -z $1 ] && [ ! -z $2 ] ; do echo "
/^$1/,/^$2/ {if (\
fun3(){ echo "/^$1/,/^$2/ {if (\%pre%~/^$1/) prev=\"\";
if (prev) print prev; prev=\%pre% }"; }

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
~/^$1/) prev=\"\"; if (prev) print prev; prev=\%pre% }"; 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_
~/^$1/) prev=\"\"; if (prev) print prev; prev=\%pre% }"; } 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
~/^$1/) prev=\"\"; if (prev) print prev; prev=\%pre% }"; 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_

Solução para a versão 3 do problema:

%pre%     
por 11.07.2016 / 21:21
0

Eu fiz mais algumas leituras e juntei algumas coisas, isso agora funciona para mim.

awk '/^date_1_/,/^date_2_/ {print}' file.txt > file2.txt
grep -v "date_2_" file2.txt > file2tmp.txt
mv file2tmp.txt file2.txt

Mas ainda requer 2 etapas e um arquivo temporário.

    
por 11.07.2016 / 18:30