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?
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]]'
où "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
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.
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
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
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
-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.