2016-03-31 5 views
0

mein Ziel ist es, die 100. Zeile in sed und es in einen String zu konvertieren, trennen Sie dann die Daten des Satzes zu Wortausdr bash für sed einer Linie in Protokoll funktioniert nicht

#!/bin/bash 
fid=log.txt; 

sentence=`expr sed -n '100p' ${fid}`; 
for word in $sentence 
do 
    echo $word 
done 

aber anscheinend hat dies gescheitert .

expr: syntax error 

Würde jemand bitte lassen Sie mich wissen, was habe ich falsch gemacht? zuvor für die Nummer hat es funktioniert.

+0

In Ihrem vorherigen sed-Befehl funktionierte es mit Zahl, weil 'expr 'kann eine Zahl als Ausdruck für ein Argument nehmen. – SLePort

Antwort

1

Die expr scheinen nicht zu einem nützlichen Zweck hier zu dienen, und wenn es so wäre, ein sed Befehl wäre sicherlich keine gültig oder nützliche Sache, um unter den meisten Umständen daran zu gehen. Sie sollten es wahrscheinlich einfach rausnehmen.

Die folgende Schleife ist jedoch ebenfalls problematisch. Unquoted variables in shell script are very frequently an error. In diesem Fall können Sie das, was Sie übergeben, nicht an die for-Schleife übergeben (das würde dazu führen, dass die Schleife nur einmal ausgeführt wird, wobei die Schleifenvariable auf die Zeichenfolge in Anführungszeichen gesetzt ist), aber Sie können nicht verhindern, dass die Shell die Platzhaltererweiterung ausführt die nicht in Anführungszeichen gesetzte Zeichenfolge. Wenn also die Zeichenfolge * enthält, erweitert die Shell diese beispielsweise auf eine Liste von Dateien im aktuellen Verzeichnis.

Glücklicherweise kann dies alles in einem nur etwas komplizierteren sed Skript getan werden.

Das heißt, wenn die Zeilennummer nicht 100 ist, löschen Sie diese Zeile und beginnen Sie mit der nächsten Zeile. Ansonsten sind wir in Zeile 100; Ersetze Leerstellen durch Zeilenumbrüche (print) und beende das Programm.

(Der Backslash Escape-Codes \t und \n sind nicht universell tragbar;.. Und \+ für die Wiederholung ist auch eine optionale Erweiterung Ich glaube, es gibt auch sed Varianten, die Semikolon als Befehlsseparator Wenigsten Wenden Sie sich sed Manpage, experiment, ., und wenn alles anderes fehlschlägt, vielleicht wechseln awk oder Perl Nur für den Fall, hier ist eine Version, die auch auf Mac OSX funktioniert:

sed '100!d 
    s/[ ][ ]*/\ 
/g;q' log.txt 

Das Zeug in den eckigen Klammern ist ein Raum und ein wörtliches Register; in Bash, mit Standard-Tastaturbelegungen, geben Sie ctrl-V ein, um eine wörtliche Registerkarte zu erstellen.)

Übrigens wird dies auch die Variable Capture Antipattern los. Es gibt gute Gründe, die Ausgabe auf eine Variable zu beschränken, aber wenn dies vermieden werden kann, erhält man oft ein einfacheres, robusteres und effizienteres sowie idiomatischeres und eleganteres Skript. (Ich sehe keinen Grund, den Protokolldateinamen in diesem Fall auch in eine Variable zu schreiben; aber in einem größeren Skript könnte es Sinn machen.)

+0

Alles wird hier gesagt. +1 – SLePort

0
#!/bin/bash 

fid=log.txt; 

sentence=$(sed -n '100p' ${fid}); 
for word in $sentence 
do 
    echo $word 
done 

setzen ein Dollarzeichen und Klammern

+0

Es ist nicht das Dollarzeichen und die Klammern, die den Unterschied gemacht haben, es ist die Entfernung von 'expr'. Backticks funktionieren auch. –

1

ich das Problem lösen nicht denken, Sie ausdr Befehl in diesem Fall benötigen. Ausdruck wird verwendet, um Berechnungen durchzuführen. Etwas wie:

expr 1 + 1 

Genau dies ist fein:

sentence=`sed -n '100p' ${fid}`;