Frage Wie kann ich PDF-Namen aus einer lftp-Protokolldatei extrahieren?


Ich habe ein Protokoll wie folgt:

2016-05-11 07:09:54 ftp://test@test.dyndns.info/test1/fool/1999/How/05%20May/test160511.pdf -> /test/keep/more/use/05/test160511.pdf 0-28442281 33.5 KiB/s

Ich muss nur "test160511.pdf" extrahieren und separate Protokolldatei einlegen.

Es ist möglich?


2
2018-05-11 07:18


Ursprung


BTW, wenn Sie ein Skriptformular bevorzugen, so können Sie laufen <command> <logfile> <outputfile>, nur erwähnen. Ich habe es zu einem One-Liner gemacht, weil die meisten Leute es ihr vorziehen :). - Jacob Vlijm


Antworten:


In einem Python-Einzeiler:

python3 -c '[print(p+".pdf") for p in [s.split(".pdf")[0] for s in open("logfile").read().split("/") if ".pdf" in s]]'

woher "logfile" ist der Pfad zu Ihrer Protokolldatei in Anführungszeichen. Ein Beispiel, mit der Eingabe Ihrer Frage, wo /home/jacob/Bureaublad/pd.txt ist meine Protokolldatei:

$ python3 -c '[print(p+".pdf") for p in [s.split(".pdf")[0] for s in open("/home/jacob/Bureaublad/pd.txt").read().split("/") if "pdf" in s]]'
test160511.pdf
test160511.pdf

Erläuterung

Der Befehl:

  • teilt den Inhalt der Datei mit dem Dellimeter auf / (Schrägstrich):

    open("logfile").read().split("/") 
    

    und sucht die Abschnitte auf, die enthalten pdf:

    for s in open("/home/jacob/Bureaublad/pd.txt").read().split("/") if "pdf" in s
    
  • Anschließend, es spaltet die gefundenen Strings durch das Dellimeter .pdf, und behält den ersten Abschnitt, der den Abschnitt zwischen / und pdf.

  • Anschließend wird die Erweiterung hinzugefügt:

    print(p+".pdf")
    

Auf diese Weise wird der Dateiname der PDFs immer korrekt abgerufen, selbst wenn der Dateiname (pdf-) Leerzeichen enthält.

Nur eindeutige Dateinamen?

Wenn Sie Dateinamen mit mehreren Vorkommen nicht wiederholen möchten:

python3 -c '[print(p+".pdf") for p in set([s.split(".pdf")[0] for s in open("logfile").read().split("/") if "pdf" in s])]'

Aus demselben Beispiel:

$ python3 -c '[print(p+".pdf") for p in set([s.split(".pdf")[0] for s in open("/home/jacob/Bureaublad/pd.txt").read().split("/") if "pdf" in s])]'
test160511.pdf

1
2018-05-11 07:55





Verwenden grep mit PCRE (-P):

grep -Po '.*/\K[^\s]+(?=\s+->)'

Beispiel:

$ grep -Po '.*/\K[^\s]+(?=\s+->)' <<<'2016-05-11 07:09:54 ftp://test@test.dyndns.info/test1/fool/1999/How/05%20May/test160511.pdf -> /test/keep/more/use/05/test160511.pdf 0-28442281 33.5 KiB/s'
test160511.pdf

Oder sed:

sed -r 's#.*/([^[:blank:]]+)[[:blank:]]+->.*#\1#'

Beispiel:

$ sed -nr 's#.*/([^[:blank:]]+)[[:blank:]]+->.*#\1#p' <<<'2016-05-11 07:09:54 ftp://test@test.dyndns.info/test1/fool/1999/How/05%20May/test160511.pdf -> /test/keep/more/use/05/test160511.pdf 0-28442281 33.5 KiB/s'
test160511.pdf

Sie können die Ausgabe mithilfe des Ausgabeumleitungsoperators speichern >:

grep .... >/where/to/save.log

Also in diesem Fall:

grep -Po '.*/\K[^\s]+(?=\s+->)' <<<'your_string' >output.log

Sie können auch eine Zwischenvariable verwenden:

temp=$(grep -Po '.*/\K[^\s]+(?=\s+->)' <<<'your_string')

und dann speichern:

echo "$temp" >output.log

3
2018-05-11 07:26



Danke für deine Wiederholung, aber in meinem lftpd Log habe ich viele viele * pdf; Also ... wie sage ich ihm, dass er alle PDF-Dateien anschaut und nur die Namen .pdf ausdruckt? :) Vielen Dank - Rumpelstiltskin
@Rumpelstiltskin Bitte seien Sie präzise, ​​wenn Sie eine Frage stellen. Beantworten Sie Ihre Frage und fügen Sie ein Stück Input und Ihre gewünschte Ausgabe hinzu. - heemayl
Also hier das Protokollbeispiel: 2016-05-08 06:27:13 test@test.dyndns.info/test1/fool/2016/search/05%20may/... -> /test/data/keep/fool/05/aa160508.pdf 0-29120689 53.1 KiB / s 2016-05-08 06:27:13 test@test.dyndns.info/test1/fool/2016/search/05%20may/... -> /test/data/keep/fool/05/cds160508.pdf 0-29120689 53.1 KiB / s 2016-05-08 06:27:13 test@test.dyndns.info/test1/fool/2016/ends/05%20may/... -> /test/data/keep/ends/05/mpf160508.pdf 0-29120689 53,1 KiB / s Brauchen nur aa160508.pdf, cds160508.pdf, mpf160508.pdf - Rumpelstiltskin
@Rumpelstiltskin Bitte fügen Sie dies zu Ihrer Frage hinzu .. - heemayl


Ein weiterer grep Lösung (file enthält das Beispiel aus Ihrer Frage):

$ grep -oP '/\K[^/]+\.pdf' file
test160511.pdf
test160511.pdf

Nur für eindeutige Namen:

$ grep -oP '/\K[^/]+\.pdf' file | sort -u
test160511.pdf

Erläuterung

  • -o : Nur den übereinstimmenden Teil der Linie drucken.
  • -P : Verwenden Sie Perl-kompatible reguläre Ausdrücke (PCRE)
  • /\K[^/]+\.pdf : a / und dann verwerfen Sie es (das ist, was die \K tut so / ist nicht in der Ausgabe enthalten). Dann passen Sie ein oder mehrere nicht/ Figuren ([^/]+), gefolgt von .pdf. Das . bedeutet "beliebiges Zeichen" in regulären Ausdrücken, also ein Literal zu entsprechen .Du musst ihm entkommen: \.
  • sort -u : Nur eindeutige Zeilen drucken.

3
2018-05-11 10:30