it-swarm.com.de

Fügen Sie nach dem angegebenen Muster mithilfe eines Shell-Skripts mehrere Zeilen in eine Datei ein

Ich möchte mit einem Shell-Skript mehrere Zeilen in eine Datei einfügen .. __ Betrachten wir den Inhalt meiner Eingabedatei: input.txt:

abcd
accd
cdef
line
web

Jetzt muss ich vier Zeilen hinter der Zeile 'cdef' in der input.txt file ..__ einfügen .. Nach dem Einfügen sollte sich meine Datei folgendermaßen ändern:

abcd
accd
cdef
line1
line2
line3
line4
line
web

Die obige Einfügung sollte ich mit dem Shell-Skript machen. Kann mir jemand helfen?

56
user27

Eine andere sed,

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

input.txt:

abcd
accd
cdef
line
web

add.txt:

line1
line2
line3
line4

Prüfung:

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

Wenn Sie die Änderungen in der input.txt-Datei übernehmen möchten. Verwenden Sie dann -i mit sed.

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

Wenn Sie einen Regex als Ausdruck verwenden möchten, müssen Sie den Tag -E mit sed verwenden.

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

Verwendung von GNU sed:

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

Wenn du angefangen hast mit:

abcd
accd
cdef
line
web

das würde produzieren:

abcd
accd
cdef
line1
line2
line3
line4
line
web

Wenn Sie die Änderungen in der Datei direkt speichern möchten, sagen Sie Folgendes:

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

awk verwenden:

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

Erklärung:

  • Sie finden die Zeile, die Sie einfügen möchten, mit /.../.
  • Sie drucken die aktuelle Zeile mit print $0.
  • RS ist eine integrierte awk-Variable, die standardmäßig auf new-line eingestellt ist. 
  • Sie fügen neue Zeilen hinzu, die durch diese Variable getrennt sind
  • 1 am Ende bewirkt, dass alle anderen Zeilen gedruckt werden. Die Verwendung von next erlaubt es uns, die aktuelle Zeile zu verhindern, da Sie sie bereits mit print $0 gedruckt haben. 

$ 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

Um Änderungen an der Datei vorzunehmen, können Sie Folgendes tun:

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

Diese Antwort ist leicht zu verstehen

  • Kopieren Sie vor dem Muster 
  • Fügen Sie Ihre Zeilen hinzu 
  • Kopieren Sie nach dem Muster
  • Ersetzen Sie die Originaldatei

    FILENAME = 'app/Providers/AuthServiceProvider.php'

SCHRITT 1 Kopie bis zum Muster

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

SCHRITT 2 fügen Sie Ihre Zeilen hinzu

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

SCHRITT 3 fügen Sie den Rest der Datei hinzu

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

Originaldatei ersetzen

mv ${FILENAME}_temp $FILENAME

wenn Sie Variablen benötigen, ersetzen Sie in Schritt 2 'EOL' durch EOL

cat << EOL >> ${FILENAME}_temp

this variable will expand: $variable1

EOL
1
lalo

Ich musste ein paar Dateien mit minimalem Werkzeug erstellen und für mich ist das Problem mit sed -e '/../r file.txt, dass die Datei erst angehängt wird, nachdem sie den Rest des Matches ausgedruckt hat.

Dies tut es nicht (alle Übereinstimmungen werden ersetzt und der Musterabgleich wird an demselben Punkt fortgesetzt)

#!/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

Sie können awk verwenden, um die Ausgabe eines Befehls in der Mitte von input.txt einzufügen.
Die einzufügenden Zeilen können die Ausgabe eines cat otherfile, ls -l oder 4 Zeilen mit einer von printf generierten Nummer sein.

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