web-dev-qa-db-fra.com

Comment puis-je extraire des noms pdf d'un fichier journal lftp?

J'ai un journal comme celui-ci:

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

je dois extraire uniquement "test160511.pdf" et mettre dans un fichier journal séparé.

C'est possible?

2
Rumpelstiltskin

Dans un python one-liner:

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

"logfile" est le chemin d'accès à votre fichier journal, entre guillemets doubles. Un exemple, en utilisant l'entrée de votre question, où /home/jacob/Bureaublad/pd.txt est mon fichier journal:

$ 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

Explication

La commande:

  • divise le contenu du fichier par le dellimètre / (barre oblique):

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

    et recherche les sections contenant pdf:

    for s in open("/home/jacob/Bureaublad/pd.txt").read().split("/") if "pdf" in s
    
  • Par la suite, il divise les chaînes trouvées par le dellimètre .pdf, et conserve la première section, qui est la section entre / et pdf.

  • par la suite, l'extension est ajoutée:

    print(p+".pdf")
    

De cette façon, le nom de fichier des pdf est toujours récupéré correctement, même si le nom de fichier (pdf-) contient des espaces.

Seuls les noms de fichiers uniques?

Si vous ne voulez pas répéter les noms de fichiers avec plusieurs occurrences:

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

Du même exemple:

$ 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
Jacob Vlijm

Utilisation de grep avec PCRE (-P):

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

Exemple:

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

Ou sed:

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

Exemple:

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

Vous pouvez enregistrer la sortie à l'aide de l'opérateur de redirection de sortie >:

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

Donc dans ce cas:

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

Vous pouvez également utiliser une variable intermédiaire:

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

puis enregistrez:

echo "$temp" >output.log
3
heemayl

Une autre solution grep (file contient l'exemple de votre question):

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

Pour les noms uniques uniquement:

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

Explication

  • -o: imprime uniquement la partie correspondante de la ligne.
  • -P: utilisez les expressions régulières compatibles Perl (PCRE)
  • /\K[^/]+\.pdf: correspond à un / puis jetez-le (c'est ce que le \K le fait, de cette façon le / n'est pas inclus dans la sortie). Ensuite, faites correspondre un ou plusieurs non/ personnages ([^/]+), suivi par .pdf. Le . signifie "n'importe quel caractère" dans les expressions régulières, donc pour faire correspondre un littéral ., vous devez y échapper: \.
  • sort -u: imprime uniquement des lignes uniques.
3
terdon