Präfix- und Suffix-Zeichenfolgen für jede Ausgabezeile des Befehls

16

Beim Schreiben eines Bash-Skripts ist ein Problem aufgetreten. Bei der grepAusgabe werden (normalerweise) viele Zeilen zurückgegeben. Ich möchte jeder dieser Ausgabezeilen einen String voranstellen und anhängen.

Ich möchte auch zu beachten , dass ich kochend lsin grep, wie:

ls | grep
SpecialBomb
quelle
2
Sie sollten nicht analysieren ls- es ist schlecht Juju. Muss es auch sein grep? Und können Sie ein Beispiel für eine Ausgabe geben?
Sobrique
1
Was soll Ihr Skript tun, wenn der Dateiname eine neue Zeile enthält?
Tai Viinikka

Antworten:

26

Mit sed:

ls | grep txt | sed 's/.*/prefix&suffix/'
Cyrus
quelle
3
Oder sedals Obermenge von grep: ls | sed -n '/txt/s/.*/prefix&suffix/p'oderls | sed -n 's/.*txt.*/prefix&suffix/p'
Stéphane Chazelas
@ StéphaneChazelas: Danke für diesen Hinweis.
Cyrus
5

Mit sed:

ls | grep pattern | sed -e 's/^/prefix/' -e 's/$/suffix/'

Beachten Sie jedoch, dass dies unter Problemen mit Dateinamen mit Zeilenvorschüben und all den verschiedenen Problemen beim Parsen leidet, lswas im Allgemeinen eine schlechte Idee ist.

Mit Perl

perl -e 'print "prefix".$_."suffix\n" for grep { m/somepattern/} glob "*"'

Hinweis - Perl grepkann wie der grepBefehl ein Muster annehmen , aber Sie können auch Dinge wie das Anwenden von Dateitests ausführen.

Z.B

grep {-d} glob "*" #filters directories.
grep { (stat)[9] > time() - 60 } glob "*" #reads file mtime and compares. 

Im grepStandard $_ist der Iterator auf den aktuellen Elementwert festgelegt, sodass Sie Regex anwenden sed/ grepformatieren oder eine Vielzahl von Aufgaben ausführen können, die auf dem Wert basieren $_.

Sobrique
quelle
Wie würde ich in Ihrem ersten Beispiel mit ´sed´ eine Variable als Suffix / Präfix einfügen?
SpecialBomb
Ändern Sie die Anführungszeichen zu und verwenden Sie einfach em.
Sobrique
2

In diesem Fall findkönnen Sie mit GNU all diese Dinge auf einmal erledigen, wodurch Pipes und möglicherweise problematisches Parsen von Folgendem vermieden werden ls:

find . -maxdepth 1 -name '[^.]*' \
  -regextype posix-extended -regex "MYPATTERN" \
  -printf 'SOMEPREFIX %f SOMESUFFIX\n'

( findIst natürlich keine gute Möglichkeit, die Ausgabe anderer Befehle willkürlich zu ändern!)

Einige Notizen:

  • -maxdepth 1und -name [^.]*lassen Sie den Namensvergleich genauso funktionieren wie ein einfaches ls(oder ls .). Sie können einen beliebigen Glob im Shell-Stil verwenden. Beachten Sie jedoch, dass "*" mit einem führenden "" übereinstimmt. in einem Namen im Gegensatz zu bash, so [^.]*bedeutet etwas , das nicht hat eine führende „“
  • MyPattern ist ein richtiger POSIX ERE (Standardtyp Emacs ist, siehe hier ), aber es muss die gesamten Dateinamen so Verwendung so etwas wie passen , .*thing.*anstatt nurthing
  • Sie können wahrscheinlich nur eines von -name/ -regexanstelle von beiden verwenden (zB -regex "[^.]. MYPATTERN. "
  • -printfunterstützt viele Dinge , %nist der schmucklose Datei- oder Verzeichnisname

(Dies kann jedoch von Ihrer Version abhängen. findLesen Sie hierzu den Abschnitt "STANDARDS CONFORMANCE" auf Ihrer Manpage.)

Als mögliche Alternative ohne externe Programme erforderlich ist , bashhat compgendie unter anderem erweitert Kleckse, das entspricht einer lsohne Optionen:

compgen -P "someprefix>" -S "<somesuffix" -G "pattern"

Dies behandelt Dateinamen mit Leerzeichen, einschließlich Zeilenumbrüchen. compgen -G "*"sollte die gleiche Ausgabe wie eine Ebene bereitstellen ls(aber beachten Sie, dass dies ls *eine völlig andere Sache ist). Sie werden noch brauchen grep, und dies kann das Problem lösen oder nicht, aber es ist eine Erwähnung wert.

mr.spuratic
quelle
0

sedund findLösungen werden in Frage gestellt, wenn Ihr Präfix / Suffix Regex-Schlüsselzeichen enthält oder wenn eine Umgebungsvariable (anstelle eines unmittelbaren Werts) übergeben werden soll. xargs+ ist hier echomöglicherweise besser geeignet.

Mit Umgebungsvariable:

ls | grep p | xargs -I % sh -c "echo $PATH/%"

Mit einer Inline:

ls | grep p | xargs -I % sh -c "echo `pwd`/%"
lashgar
quelle