2
votes

Bash divisant une chaîne de plusieurs lignes par un délimiteur de plusieurs caractères en un tableau

J'ai recherché un sujet similaire ici, mais la plupart des questions comprenaient un délimiteur à un seul caractère.

J'ai cet exemple de texte:

Some text here,
continuing on next lineDELIMITERSecond chunk of text
which may as well continue on next lineDELIMITERFinal chunk

Et le résultat souhaité est une liste ( extrait = () ) qui contient:

  1. Du texte ici, continuer sur la ligne suivante
  2. Deuxième morceau de texte qui peut aussi bien continuer sur la ligne suivante
  3. Morceau final

Comme on peut le voir dans l'exemple, "DELIMITER" est utilisé comme séparateur de division.

J'ai essayé de nombreux échantillons sur SO, y compris awk, en remplaçant etc.


2 commentaires

Pas clair, veuillez mentionner plus clairement les résultats attendus. Ajoutez également vos efforts dans votre message.


Votre exigence n'est pas claire? Suggérez-vous que même si l'entrée génère plusieurs lignes, vous voulez que le contenu soit divisé en une seule chaîne? c'est-à-dire que la chaîne finale doit être Du texte ici, continuant sur la ligne suivante une entrée dans le tableau final?


6 Réponses :


0
votes

Vous pouvez essayer quelque chose comme:

awk 'BEGIN {RS="DELIMITER";} {print}' input_file

Et ensuite l'assigner à une variable, etc ...


0 commentaires

4
votes

Si vous ne souhaitez pas modifier la valeur par défaut de RS , veuillez essayer de suivre.

awk '{gsub("DELIMITER",ORS)} 1' Input_file


6 commentaires

Comment le mettre dans un tableau? J'ai essayé de le mettre entre parenthèses () mais accéder à des éléments comme [0] [1] donne les mots (à cause de la séparation de l'espace)


@Hubbs try: tab = ($ (awk '{gsub ("DELIMITER", "\" ")} 1' infile)); echo" $ {tab [1]} "


@ctac_, merci ctac, si vous le souhaitez, vous pouvez modifier ma réponse ou je pourrais l'ajouter à ma solution aussi, faites-le moi savoir.


@ RavinderSingh13 ajoutez-le dans votre réponse.


@ctac_ L'utilisation de ceci me donne comme sortie un seul mot au lieu de la phrase entière avant le délimiteur.


@Hubbs désolé IFS manquant. Essayez IFS = '"' tab = ($ (awk '{gsub (" DELIMITER "," \ "")} 1' infile)); echo $ {tab [1]}



1
votes

Avec AWK, essayez ce qui suit:

1. Some text here,
continuing on next line
2. Second chunk of text
which may as well continue on next line
3. Final chunk

qui donne:

awk -v RS='^$' -v FS='DELIMITER' '{
    n = split($0, extracted)
    for (i=1; i<=n; i++) {
        print i". "extracted[i]
    }
}' sample.txt

Si vous avez besoin de transférer le tableau awk vers le tableau bash , une étape supplémentaire sera nécessaire en fonction du processus suivant sur le tableau.


0 commentaires

1
votes

Vous pouvez essayer d'utiliser des tableaux.

#!/bin/bash
str="continuing on next lineDELIMITERSecond chunk of text
which may as well continue on next lineDELIMITERFinal chunk";


delimiter=DELIMITER
s=$str$delimiter

array=();
while [[ $s ]]; do
array+=( "${s%%"$delimiter"*}" );
s=${s#*"$delimiter"};
done;
declare -p array

cela divisera votre texte en tableau en fonction de votre délimiteur le résultat sera un tableau de votre texte.

array = ([0] = "continue sur next line "[1] = $ 'Deuxième morceau de texte \ nqui peut tout aussi bien continuer sur la ligne suivante' [2] =" Morceau final ")

vous pouvez accéder à chaque ligne en utilisant les indices du tableau ou vous pouvez imprimer toutes les lignes en utilisant printf '% s \ n' "$ {array [@]}"

les résultats seront

continuer sur la ligne suivante Deuxième morceau de texte qui peut aussi bien continuer sur la ligne suivante Dernière partie

La solution vous donne l'opportunité de faire beaucoup avec votre texte.


0 commentaires

0
votes

Je pense que le plus grand défi de la question est de gérer correctement l'espace, la nouvelle ligne et DELIMITER, puis de mettre toutes les choses dans un tableau. C'était pour diviser le fichier uniquement, alors ce serait trop facile. Que diriez-vous de ce modèle:

     1  extracted=(); read -r -d '' item <<-DELIMITER
     2  Some text here,
     3  continuing on next line
     4  DELIMITER
     5  extracted+=("$item"); read -r -d "" item <<-DELIMITER
     6  Second chunk of text
     7  which may as well continue on next line
     8  DELIMITER
     9  extracted+=("$item"); read -r -d "" item <<-DELIMITER
    10  Final chunk
    11  DELIMITER
    12  extracted+=("$item")
0: Some text here,
continuing on next line
1: Second chunk of text
which may as well continue on next line
2: Final chunk

Résultats

#!/bin/bash
gencode(){
  echo -e "extracted=(); read -r -d '' item <<-DELIMITER"
  sed 's:DELIMITER:\n&\nextracted+=("$item"); read -r -d "" item <<-&\n:' Input_file;
  echo -e "DELIMITER\n"'extracted+=("$item")'
}
gencode|cat -n                                 # for explaination purpose only
eval "`gencode`"                               # do not remove "eval"
for (( i=0; i < ${#extracted[@]}; i++ )); do   # print results
  echo "$i: ${extracted[i]}"
done


0 commentaires

0
votes

Vous pouvez essayer Perl. Avec l'option -0777, perl transforme tout le fichier dans une variable $ _. Vous pouvez ensuite diviser le contenu à l'aide du DELIMITER. Vérifiez ceci.

$ perl -0777 -ne '@x=split("DELIMITER"); for(@x) { print ++$i,". $_\n"  } ' hubbs.txt
1. Some text here,
continuing on next line
2. Second chunk of text
which may as well continue on next line
3. Final chunk


$

Ajout de positions de tableau lors de l'impression

$ perl -0777 -ne '@x=split("DELIMITER");print join("\n\n",@x) ' hubbs.txt
Some text here,
continuing on next line

Second chunk of text
which may as well continue on next line

Final chunk

$


0 commentaires