sed im script...?

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
latenite
Beiträge: 688
Registriert: 14.05.2007 01:04:23

sed im script...?

Beitrag von latenite » 20.09.2009 00:03:56

Hallo Leute

ich habe hier ein kleines Script das:
1. in ein file
2. an bestimmter Zeile
3. Text einfügt

Leider geht es nur mit festen Zahlen und Text. Wenn ich übergebene Variablen nutze gibt sed Fehlermelduge naus

Ich würde es gern so aufrufen können:

Code: Alles auswählen

./addline.sh ./thefile.txt 3 neuertext

Code: Alles auswählen

#!/bin/bash

# $1 is the file you want to edit
# $2 is the line where you want to start adding
# $3 is the text you want to add

LINENUMBER=$2
TEXT=$3

sed '3i\ newtext' $1 > $1.modified
mv $1.modified $1

# not working
echo $LINENUMBER

sed '$LINENUMBERi\ $TEXT' $1 > $1.modified
mv $1.modified $1
danke schon mal für eure Hilfe :)

latenite
Beiträge: 688
Registriert: 14.05.2007 01:04:23

Re: sed im script...?

Beitrag von latenite » 20.09.2009 11:31:47

keiner ne Idee? :cry:

chr.gogolin
Beiträge: 441
Registriert: 12.10.2005 23:09:28
Lizenz eigener Beiträge: MIT Lizenz
Kontaktdaten:

Re: sed im script...?

Beitrag von chr.gogolin » 20.09.2009 12:20:14

Das Problem ist die Zeile:

Code: Alles auswählen

sed '$LINENUMBERi\ $TEXT' $1 > $1.modified
1) Zwischen den ' ' werden variablen nicht "eingesetzt". Ist $LINENUMBER=3, $TEXT=text und $1=file, so sieht sed nicht

Code: Alles auswählen

sed 3i\ text file > file.modified
sondern

Code: Alles auswählen

sed '$LINENUMBERi\ $TEXT' file > file.modified
Richtig wären " " anstelle von ' '.

2) Selbst wenn du die richtigen Anführungszeichen verwendest wird $LINENUMBERi nicht in 3i expandiert, sondern die shell denkt du würdest die Variable $LINENUMBERi meinen. Was du brauchst ist ${LINENUMBER}i.

Ohne es getestet zu haben müsste folgendes funktionieren:

Code: Alles auswählen

sed "${LINENUMBER}i\ $TEXT" $1 > $1.modified
"Linux supports the notion of a command line or a shell for the same reason that only children read books with only pictures in them." - Bill Garrett

Benutzeravatar
detix
Beiträge: 1743
Registriert: 07.02.2007 18:51:28
Wohnort: MK

Re: sed im script...?

Beitrag von detix » 20.09.2009 12:44:37

Eine andere Variante, ohne anschl. 'mv' und Leerzeichen vorm Text (alles Einzelticks):

Code: Alles auswählen

sed -i ''$LINENUMBER'i\'$TEXT'' $1
Gruß an alle Debianer, und immer daran denken:
Macht ohne Haftung funktioniert nicht!

latenite
Beiträge: 688
Registriert: 14.05.2007 01:04:23

Re: sed im script...?

Beitrag von latenite » 20.09.2009 13:23:15

hey danke das ging bestens. :)
leider kann ich aber nur EIN Wort einfügen.

Code: Alles auswählen

./addline.sh ./thefile.txt 3 neuertext
geht
aber

Code: Alles auswählen

./addline.sh ./thefile.txt 3 neueswort1 neueswort2
added nur "neueswort1"

laut sed manpage sollte es aber geanu so funktionieren und wenn ich mehrere Zeilen einfügen will dann sollte es so gehen:

Code: Alles auswählen

./addline.sh ./thefile.txt 3 neueswort1 neueswort2\
neueswort3\
neueswort4\
was mache ich da noch falsch? danke für eure Hilfe :)

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: sed im script...?

Beitrag von Duff » 20.09.2009 13:49:12

In $3 wird nur die Variable bis zum Leerzeichen gespeichert.
Kannst du überprüfen, in dem du zu Beginn des Skriptes die Variablen ausgibst.

Du müsstest die Variablen mit Leerzeichen in "-Kommatas packen.

Code: Alles auswählen

./addline.sh ./thefile.txt 3 "Wort1 und Wort2"
Oh, yeah!

latenite
Beiträge: 688
Registriert: 14.05.2007 01:04:23

Re: sed im script...?

Beitrag von latenite » 20.09.2009 18:43:42

mag nicht.. :(

Code: Alles auswählen

0:503:kai@desktop ~/Desktop [2]$ ./addline.sh ./menu.lst 3 "wort1 wort 2"
sed: kann wort nicht lesen: Datei oder Verzeichnis nicht gefunden
sed: kann 2 nicht lesen: Datei oder Verzeichnis nicht gefunden
0:504:kai@desktop ~/Desktop [
mit diesem code

Code: Alles auswählen

#!/bin/bash

# $1 is the file you want to edit
# $2 is the line where you want to start adding
# $3 is the text you want to add

LINENUMBER=$2
TEXT=$3

sed -i ''$LINENUMBER'i\'$TEXT'' $1
danke :)

Benutzeravatar
Meillo
Moderator
Beiträge: 9254
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: sed im script...?

Beitrag von Meillo » 20.09.2009 19:03:24

latenite hat geschrieben:

Code: Alles auswählen

sed '3i\ newtext' $1 > $1.modified
mv $1.modified $1
Also wenn ich sowas sehen, dann frage ich mich warum viele `sed' für nicht-Pipeline Aufgaben verwenden. Wo doch `sed' nur eine Abart von `ed' die den speziellen Fall Pipeline abdeckt. Für normale Dateibearbeitung ist ja `ed' da. `sed' gibt es _nur_ weil `ed' schlecht für Pipelines ist. (Ich würde das fast als Ironie der Geschichte bezeichnen.)

Also warum nicht `ed' nehmen für Dinge für die `ed' da ist?

Hier mal obiger (fehlerhafter) Code 1:1 übersetzt:

Code: Alles auswählen

ed -s $1 <<EOF
3i
newtext
.
w
q
EOF

Ich hatte dieses Problem Vorgestern erst und habe mir deshalb ein ähnliches Script geschrieben (das allerdings ein Filter ist):

Code: Alles auswählen

#!/bin/sh

if [ $# -ne 2 ] ; then
        echo "usage: insline AFTER TEXT"
        echo "prints stdin to stdout but inserts TEXT after line AFTER"
        echo "if AFTER is 0 or the last line, then use cat(1) instead"
        exit 1
fi

awk -v after="$1" -v text="$2" '
        { print }

        NR==after {
                print text
        }
'

(Witzigerweise heißt dein Script addline und macht ein insert -- meines heißt insline, macht aber ein append. ;-) )


latenite hat geschrieben:mag nicht.. :(

Code: Alles auswählen

sed -i ''$LINENUMBER'i\'$TEXT'' $1
Nicht zwei Singlequotes ('') sondern ein Doublequote (")!
Use ed once in a while!

Benutzeravatar
Meillo
Moderator
Beiträge: 9254
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: sed im script...?

Beitrag von Meillo » 20.09.2009 19:14:58

Code: Alles auswählen

#!/bin/bash

# $1 is the file you want to edit
# $2 is the line where you want to start adding
# $3 is the text you want to add

LINENUMBER="$2"
TEXT="$3"

sed -i "${LINENUMBER}i\$TEXT" "$1"
(Habe gerade empirisch herausgefunden, dass das `i'-Kommando bei `sed' wohl nicht so recht portabel ist. Zumindest läuft es so unter NetBSD nicht und eine portable Version (Zeilenumbruch?) habe ich auf die Schnelle nicht hingekriegt. Aber ich bin ja sowieso für `ed' wenn du eine Datei in-place verändern willst.)
Use ed once in a while!

Benutzeravatar
detix
Beiträge: 1743
Registriert: 07.02.2007 18:51:28
Wohnort: MK

Re: sed im script...?

Beitrag von detix » 20.09.2009 19:52:02

Meillo hat geschrieben:

Code: Alles auswählen

Habe gerade empirisch herausgefunden, dass das `i'-Kommando bei `sed' wohl nicht so recht portabel ist.[/quote]
So wird es wohl sein, hier funktioniert keiner deiner beiden Vorschläge
[quote]sed -i "${LINENUMBER}i\$TEXT" "$1"
sed -i ''$LINENUMBER'i\'$TEXT'' $1 #Nicht zwei Singlequotes ('') sondern ein Doublequote (")![/quote]
Es müssen hier (squeeze) alles Einzelticks sein (getestet).
Falls [color=#0000FF]sed[/color] weiterhin benutzt werden soll und die Anzahl der Parameter unbekannt ist,
gehts wahrscheinlich besser mit [color=#0000FF]shift[/color] und zusätzlicher Schleife.
Gruß an alle Debianer, und immer daran denken:
Macht ohne Haftung funktioniert nicht!

Benutzeravatar
Meillo
Moderator
Beiträge: 9254
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: sed im script...?

Beitrag von Meillo » 20.09.2009 20:00:32

detix hat geschrieben:
Meillo hat geschrieben:

Code: Alles auswählen

Habe gerade empirisch herausgefunden, dass das `i'-Kommando bei `sed' wohl nicht so recht portabel ist.[/quote]
So wird es wohl sein, hier funktioniert keiner deiner beiden Vorschläge[/quote]
Es war nur ein Vorschlag der nur mit einem Wort in $TEXT geteste wurde. ;-)

[quote]Falls [color=#0000FF]sed[/color] weiterhin benutzt werden soll [...][/quote]
Das ist halt das ganze Problem!
Use ed once in a while!

latenite
Beiträge: 688
Registriert: 14.05.2007 01:04:23

Re: sed im script...?

Beitrag von latenite » 20.09.2009 23:55:30

Hihi das is ja echt tragisch mit dem "ed" :? :roll: :wink:
Ich hglaub ich hab das noch NIE benutzt :D ...werd ich aber ab heute. Danke

Code: Alles auswählen

#!/bin/bash

# $1 is the file you want to edit
# $2 is the line where you want to start adding
# $3 is the text you want to add

FILE=$1
LINENUMBER=$2
TEXT=$3

ed -s $FILE <<EOF
${LINENUMBER}i
$TEXT
.
w
q
EOF
funktioniert erst mal für EINE beliebige Zeile. Was noch fehlt ist das ich einen Textblock einfügen kann.
Ich habe vor meine /boot/grub/menu.list zu editieren nach dem ich einen Kernel gebaut habe.
Also müsste ich ungefähr so was einfügen können:

Code: Alles auswählen

title		Debian GNU/Linux, kernel 2.6.30-1-686
root		(hd0,0)
kernel		/boot/vmlinuz-2.6.30-1-686 root=/dev/sda1 ro quiet
initrd		/boot/initrd.img-2.6.30-1-686
aber wie?

Code: Alles auswählen

BLOCK=`echo -e "line1 \n
line2 \n
line3 \n
line4"`

echo $BLOCK
funktioniert nicht und "raubt" alle Zeilenumbrüche..


Danke :D

Benutzeravatar
GoKi
Beiträge: 2068
Registriert: 04.07.2003 23:08:56
Lizenz eigener Beiträge: MIT Lizenz

Re: sed im script...?

Beitrag von GoKi » 21.09.2009 00:08:21

Mal so am Rande, wieso nicht update-grub?
MfG GoKi
:wq

latenite
Beiträge: 688
Registriert: 14.05.2007 01:04:23

Re: sed im script...?

Beitrag von latenite » 21.09.2009 11:44:49

weil ich noch so Sachen wie "vga=0x031b" einbauen will. :)

latenite
Beiträge: 688
Registriert: 14.05.2007 01:04:23

Re: sed im script...?

Beitrag von latenite » 21.09.2009 14:56:46

so sollte es gehen:

Code: Alles auswählen

#!/bin/bash

FILE=$1
LINENUMBER=$2
TEXT=$3


lines=$(awk 'END {print NR}' $FILE)

diff=$(($lines-$LINENUMBER))
start=$((lines - $diff))
awk -v pos="$start" '{
if(NR<=pos)
print
}' $FILE
echo "----------"
awk -v pos="$start" '{
if(NR>pos)
print
}' $FILE
nur muss ich das jetzt noch in die Datei schreiben....wie mache ich das? Momentan ist das ja nur output im termianl.

danke

Antworten