Execute o shell script até deixar uma linha no arquivo

0
#!/bin/sh
echo "file to split?"
read file
f=0
until ! [ -s $file ];
do
        grep -n "<text" $file > titles.txt
        lines=$(cat titles.txt| sed -n 2'p' | sed -r 's/^([0-9]*).*//g')
        f=$((f+1))
        substrac="$(($lines-1))"
        head -$substrac $file > $f
        sed -i '1,'$substrac'd' $file
        echo "file \"$f\" generated"
done

Esse script é executado até que $file esteja vazio, mas eu preciso que ele seja executado até que haja 1 linha no arquivo "titles.txt" ou uma ocorrência de " <text " no arquivo $.

Eu tentei:

while :
do
        count=$(grep "<text" $file | wc -l)
if [ $count > 1 ]
then

e:

while :
count=$(cat titles.txt | wc -l);
do
until [ $count -eq 1 ]; do

Mas eu não posso fazer o script parar nesse ponto, tenho certeza que estou fazendo algo errado mas não consigo encontrar o que ...

    
por Andrés Chandía 05.05.2018 / 21:46

2 respostas

1

Se o arquivo for um arquivo XML bem formado e você quiser extrair os <text> nodes em arquivos separados, o seguinte fará isso usando XMLStarlet:

#!/bin/sh

infile="$1"

xmlstarlet sel -t -v '//text/@id' -nl "$infile" |
while read id; do
    xmlstarlet sel -t --var id="'$id'" -v '//text[@id = $id]' "$infile" >"$id.txt"
done

Dado o nome do caminho de um arquivo como o seguinte na linha de comando,

<?xml version="1.0"?>
<root>
  <text id="cade2296-1">
The first text, called "cade2296-1".
</text>
  <text id="cafr3062-1">
The second text, called "cafr3062-1".
</text>
</root>

... isso criaria os dois arquivos, cade2296-1.txt e cafr3062-1.txt , no diretório atual, com o conteúdo das duas tags <text> no arquivo original.

Os nomes dos arquivos são retirados do atributo id das tags <text> . Esses valores id são primeiro extraídos do XML e usados no loop para extrair os valores relevantes da tag.

A alteração de -v para -c na invocação do XMLStarlet dentro do loop daria a você uma cópia das tags <text> XML, e não apenas os dados na tag.

    
por 06.05.2018 / 14:20
-1

Sim, graças a George Vasiliou eu fiz o trabalho funcionar, agora o roteiro segue assim:

#!/bin/sh
echo "file to split?"
read file

# This variable is to name resulting files
f=0

while :
do
    # Count how many occurrences of "<text" are in the file to split
    count=$(grep "<text" "$file" | wc -l)
if [ "$count" -gt 1 ]
then

    # Send the occurrences of "<text" with their line number to the titles.txt file
    grep -n "<text" "$file" > titles.txt

    # From the second line of titles get the line number
    lines=$(cat titles.txt| sed -n 2'p' | sed -r 's/^([0-9]*).*//g')

    # Every time the script is run the resulting file gets the next number as name      
    f=$((f+1))

    # From the line number obtained at the second line substract 1
    substrac="$(($lines-1))"

    # Create a new file taking the amount of lines indicated by the substraction from the splitting file
    head -"$substrac" "$file" > "$f"

    # Delete the lines corresponding to the newly created file from the splitting file to start the process over
    sed -i '1,'"$substrac"'d' "$file"
    echo "file \"$f\" generated"
else
    echo "process finished!"
    exit 1;
fi
done

Explicação: Eu tenho um enorme arquivo de texto com este formato:

  <text id="cade2296-1">
  many
  undetermined
  lines
  ...
 </text>

 The same schema repeteated undetermined times

  <text id="cafr3062-1">
  many
  undetermined
  lines
  ...
 </text>

E o que preciso é de cada esquema em um arquivo diferente.

    
por 05.05.2018 / 22:15