Wie kann ich eine bestimmte Zeile als Befehl in einer Textdatei ausführen?

11

Manchmal muss ich einen einzelnen Befehl ausführen, der sich in einem Shell-Skript befindet.

Ich weiß bereits, sed -n 'line_num p'dass ich diese Zeile drucken kann. Aber wie kann ich diese ausgedruckte Zeile als Befehl ausführen?

Zen
quelle

Antworten:

9

Versuchen Sie diesen Kerl =):

sed -n 'line_num p' | bash

oder

"$(sed -n 'line_num p')"
Gilles Quenot
quelle
@mikeserv Ich bin daran interessiert, den Kontext dieser Aussage für meine eigene Ausbildung zu kennen.
Bratchley
Sie müssen kein Leerzeichen zwischen line_numund setzen. pWenn line_numbeispielsweise 123 lautet, können Sie dies tun sed -n 123p | bash. Und wenn shes reicht, dann verwenden Sie einfach shstatt bash.
Janos
Könnte sed -n 'line_num p' | shalso eine andere Lösung sein? Ist dieser mehr Kompatibilität?
Zen
1
@Zen - das hängt davon ab, auf welche Shell das Skript abzielt. Es hängt auch davon ab, welche Shell shtatsächlich ist. Auf Debian (und abgeleiteten) Systemen shist in der Regel dash. Wenn das Skript für geschrieben wurde dash (oder auf andere Weise auf portabler Syntax basiert ), dann wahrscheinlich, ja, aber wenn es für geschrieben wurde, bashdann fast definitiv nicht.
Mikeserv
Könnte dies mit der Verlaufsdatei geschehen, damit ich, wenn ich ausgeführt werde historyund sehe, dass ich Zeile 900 ausführen möchte, Zeile 900 irgendwie ausführen kann?
Codecowboy
3

Wenn Sie dies interaktiv tun, können Sie die Zeile in den Bash-Verlauf schreiben:

history -s "$(sed -n 'line_num p')"

Drücken Sie dann Enter, um die Zeile in den Readline-Puffer einzufügen, und führen Sie sie aus. Das gibt Ihnen die Möglichkeit, einen Blick auf die Linie zu werfen, bevor es zu spät ist.

Rici
quelle
Das ist ziemlich klug und wahrscheinlich eine gute Annahme.
Mikeserv
Was bedeutet diese Option hier? Ich kann keine Erklärungen finden inman history
Zen
@zen: historyist eingebaut, daher ist es dokumentiert in help history(oder man bash, aber das ist viel Lesen). Wenn Sie das Obige zitieren, history -swerden "die ARGs als einzelner Eintrag an die Verlaufsliste
angehängt
2

Du kannst tun...

{ head -n"$((NUM-1))"; IFS= read -r line; } </path/to/script >/dev/null
eval "$line"

Dadurch wird nur die $NUMZeile aus Ihrem Skript in der Shell-Variablen abgerufen $lineund dann als Befehl in der aktuellen Shell ausgewertet.

Ein anderer Weg, dies zu tun, könnte folgendermaßen aussehen:

 </path/to/script sed "${NUM}q;d" >/tmp/"$$"
 . /tmp/"$$" ; rm /tmp/"$$"
mikeserv
quelle
1
'eval' ist eine häufige Rechtschreibfehler von 'böse'. Wenn eval die Antwort ist, stellen Sie sicherlich die falsche Frage. Siehe mywiki.wooledge.org/BashFAQ/048
Gilles Quenot
1
Jep. Jeder liebt eval.
Mikeserv
gnu sedhat die eFlagge so etwas sed "${NUM}"'!d;s/^//e;q'würde auch funktionieren
don_crissti
1

Bearbeiten Sie Ihr Skript mit vim (vi unter Linux)? Fügen Sie in vi eine Zuordnung hinzu:

:nmap <F4> Y:!<C-R>"<C-H><CR>

und danach, wenn Sie in vi auf der interessanten Linie sind, drücken Sie F4

Walter A.
quelle
-2

In bash können Sie den folgenden Befehl ausführen:

for line in $(cat file.txt); do command $line; done
Yan
quelle