web-dev-qa-db-fra.com

Insérer plusieurs lignes dans un fichier après le modèle spécifié à l'aide d'un script Shell

Je souhaite insérer plusieurs lignes dans un fichier à l'aide du script Shell . Considérons que le contenu de mon fichier d'entrée est le suivant: input.txt:

abcd
accd
cdef
line
web

Maintenant, je dois insérer quatre lignes après la ligne 'cdef' dans le fichier input.txt file . Après avoir inséré mon fichier, il devrait changer comme suit:

abcd
accd
cdef
line1
line2
line3
line4
line
web

L'insertion ci-dessus que je devrais faire en utilisant le script Shell. Quelqu'un peut-il m'aider?

56
user27

Un autre sed,

sed '/cdef/r add.txt' input.txt

input.txt:

abcd
accd
cdef
line
web

add.txt:

line1
line2
line3
line4

Test:

sat:~# sed '/cdef/r add.txt' input.txt
abcd
accd
cdef
line1
line2
line3
line4
line
web

Si vous souhaitez appliquer les modifications dans le fichier input.txt. Ensuite, utilisez -i avec sed.

sed -i '/cdef/r add.txt' input.txt

Si vous voulez utiliser une expression régulière comme expression, vous devez utiliser la balise -E avec sed.

sed -E '/RegexPattern/r add.txt' input.txt
78
sat

Utilisation de GNU sed:

sed "/cdef/aline1\nline2\nline3\nline4" input.txt

Si vous avez commencé avec:

abcd
accd
cdef
line
web

cela produirait:

abcd
accd
cdef
line1
line2
line3
line4
line
web

Si vous souhaitez enregistrer les modifications dans le fichier, dites:

sed -i "/cdef/aline1\nline2\nline3\nline4" input.txt
29
devnull

Utiliser awk:

awk '/cdef/{print $0 RS "line1" RS "line2" RS "line3" RS "line4";next}1' input.txt 

Explication:

  • Vous trouvez la ligne que vous voulez insérer en utilisant /.../
  • Vous imprimez la ligne en cours en utilisant print $0
  • RS est une variable awk intégrée, définie par défaut sur new-line
  • Vous ajoutez de nouvelles lignes séparées par cette variable
  • 1 à la fin entraîne l'impression de toutes les lignes. Utiliser next avant cela nous permet d'empêcher la ligne en cours puisque vous l'avez déjà imprimée avec print $0

$ awk '/cdef/{print $0 RS "line1" RS "line2" RS "line3" RS "line4";next}1' input.txt
abcd
accd
cdef
line1
line2
line3
line4
line
web

Pour modifier le fichier, vous pouvez effectuer les tâches suivantes:

awk '...' input.txt > tmp && mv tmp input.txt
13
jaypal singh
sed '/^cdef$/r'<(
    echo "line1"
    echo "line2"
    echo "line3"
    echo "line4"
) -i -- input.txt
12
rindeal

Cette réponse est facile à comprendre

  • Copier avant le motif 
  • Ajoutez vos lignes 
  • Copier après le motif
  • Remplacer le fichier d'origine

    FILENAME = 'app/Providers/AuthServiceProvider.php'

ÉTAPE 1 copie jusqu'au motif

sed '/THEPATTERNYOUARELOOKINGFOR/Q' $FILENAME >>${FILENAME}_temp

ÉTAPE 2 ajoutez vos lignes

cat << 'EOL' >> ${FILENAME}_temp

HERE YOU COPY AND
PASTE MULTIPLE
LINES, ALSO YOU CAN
//WRITE COMMENTS

AND NEW LINES
AND SPECIAL CHARS LIKE $THISONE

EOL

ÉTAPE 3 ajouter le reste du fichier

grep -A 9999 'THEPATTERNYOUARELOOKINGFOR' $FILENAME >>${FILENAME}_temp

REMPLACER le fichier d'origine

mv ${FILENAME}_temp $FILENAME

si vous avez besoin de variables, remplacez 'EOL' par EOL à l'étape 2

cat << EOL >> ${FILENAME}_temp

this variable will expand: $variable1

EOL
1
lalo

Je devais modéliser quelques fichiers avec un minimum d’outillage. Pour moi, le problème avec sed -e '/../r file.txt ci-dessus est qu’il n’ajoute le fichier qu’après l’impression du reste de la correspondance.

Cela ne le fait pas (toutes les correspondances sont remplacées et la correspondance de motif continue à partir du même point)

#!/bin/bash

TEMPDIR=$(mktemp -d "${TMPDIR:-/tmp/}$(basename $0).XXXXXXXXXXXX")
# remove on exit
trap "rm -rf $TEMPDIR" EXIT

DCTEMPLATE=$TEMPDIR/dctemplate.txt
DCTEMPFILE=$TEMPDIR/dctempfile.txt

# template that will replace
printf "0replacement
1${Shell} data
2anotherlinenoEOL" > $DCTEMPLATE

# test data
echo -e "xxy \n987 \nxx xx\n yz yxxyy" > $DCTEMPFILE

# print original for debug
echo "---8<--- $DCTEMPFILE"
cat $DCTEMPFILE
echo "---8<--- $DCTEMPLATE"
cat $DCTEMPLATE
echo "---8<---"

# replace 'xx' -> contents of $DCTEMPFILE
Perl -e "our \$fname = '${DCTEMPLATE}';" -pe 's/xx/`cat $fname`/eg' ${DCTEMPFILE}
0
Pasi Savolainen

Vous pouvez utiliser awk pour insérer le résultat d'une commande au milieu de input.txt.
Les lignes à insérer peuvent être la sortie d'un cat otherfile, ls -l ou de 4 lignes avec un nombre généré par printf.

awk 'NR==FNR {a[NR]=$0;next}
    {print}
    /cdef/ {for (i=1; i <= length(a); i++) { print a[i] }}'
    <(printf "%s\n" line{1..4}) input.txt
0
Walter A