Dividir arquivos com base na pesquisa de padrões. Dividir o nome do arquivo com o padrão que procuramos

2

Eu tenho um arquivo como mostrado abaixo:

###PSTERS###
LINE1
LINE2
###PSTADS###
LINE3
LINE4
###PSTEEE###
LINE5
LINE6

Eu preciso gerar 3 arquivos como iguais (nomes de arquivos são o padrão que estamos pesquisando):

PSTERS.txt:

LINE1
LINE2

PSTADS.txt:

LINE3
LINE4

PSTEEE.txt:

LINE5
LINE6

Como posso fazer isso? Eu tentei o script abaixo, mas está falhando com um erro de sintaxe do awk:

#!/bin/bash
#This script will take 2 parameters as input.
# 1. Source File Path
# 2. Source File name as input

SOURCE_PATH=$1
SOURCE_FILE=$2

#Get the list of patterns we need to check from the Main source file

cd $SOURCE_PATH
pattern_list='grep -e '^\#' $SOURCE_FILE | cut -d'#' -f4'
echo ${pattern_list}

#Split the Source File for each pattern in the variable pattern_list

for pattern in ${pattern_list}
do
        cd $SOURCE_PATH
        awk '/\#\#\#'$pattern'/{x='$pattern';next}{print > x;}' $SOURCE_FILE
done
    
por Sreekesh Darshi 10.03.2017 / 14:32

2 respostas

2

Você está adotando uma abordagem muito complicada. Não há necessidade de um script de shell, isso é um awk one-liner:

awk '{if(gsub(/#+/,"")){name=$0;}else{print > name".txt"}}' file

O gsub é "substituição global". Portanto, o acima significa "se uma linha tiver qualquer # , remova-os (substitua por nada) e defina a variável" name "para o conteúdo da linha". Como a linha agora será tudo que sobrou depois de remover o # , name será o padrão. Em seguida, se a linha não corresponder a # (se a substituição falhar), imprima a linha em um arquivo cujo nome é o valor atual de name e .txt .

Se você ainda precisar do script de wrapper, use:

#!/bin/bash -
#This script will take 1 parameter as input: the target file path
targetFile="$1"        
targetDir=$(dirname -- "$targetFile")
targetFile=$(basename -- "$targetFile")
cd -P -- "$targetDir" || exit
awk '{if(gsub(/#+/,"")){name=$0;}else{print > name".txt"}}' < "$targetFile"
    
por 10.03.2017 / 14:53
0

Podemos usar relative addressing do editor ed para obter isso.

A tarefa envolve a extração do número da linha de todas as linhas # no arquivo de entrada na primeira passagem. Em seguida, geramos uma série de comandos ed para realizar o trabalho. O lado direito exibe o conteúdo do espaço de padrão conforme ele é moldado pelo sed scrivener

sed -e '$s/.*/$/;$q;/^#/!d;=' inputfile |
sed -e '
   N;N;h;                            # p.s.:  1\n###PSTERS###\n4$

   s/^[1-9][0-9]*/&+/; /\$$/!s/$/-/; # p.s.:  1+\n###PSTERS###\n4-$

   s/\n\(.*\)\n\(.*\)/,w .txt/; # p.s.:   1+,4-w ###PSTERS###.txt$

   s/#//gp;g;                       # p.s.:   1+,4-w PSTERS.txt

   s/.*\n/\n/; $!D; s/.*/q/
' |
ed -s - inputfile
    
por 11.03.2017 / 04:21

Tags