#!/bin/bash # Initialisation des variables pour les options programme=$(basename $0) substitut=$(echo $programme | sed 's/./ /g') version='1.2.5' modif='25/07/2022' function usage { echo "Usage : $programme -s sid -q requête [ -p (début:fin|[124]week) ] " echo " $substitut [ -b [WOS:]base ]* [ -f champs ]* [ -t CH:(A|D) ] " echo " $substitut [ -n notices ] [ -j cookie_jar ] [ -i ]" echo " $programme -h " } function aide { cat << EOT Usage ===== $programme -s sid -q requête [ -p (début:fin|[124]week) ] $substitut [ -b [WOS:]base ]* [ -f champs ]* [ -t CH:[AD] ] $substitut [ -n notices ] [ -j cookie_jar ] [ -i ] $programme -h Options principales =================== -h affiche cette aide -p limite la recherche dans la base de données à la période indiquée sous forme aaaa-mm-jj:aaaa-mm-jj (e.g., “2000-01-01:2020-07-31”) ou sous forme “1week”, “2week” ou “4week” -q fournit la requête à envoyer (entre simples ou doubles quotes si elle contient des espaces ou des caractères spéciaux) -s indique le jeton d’authentification “SID” obtenu avec le programme d’authentification à l’API WoS Autres options ============== -b limite la recherche à une ou plusieurs bases (e.g. “WOS:SCI”). Cette option est répétitive et “WOS:” est facultatif (par défaut, la recherche se fait sur l’ensemble du WoS) -f limite les champs présents dans les notices téléchargées. Cette option est répétitive (par défaut, tous les champs sont présents) -i ajoute dans la réponse de l’API la liste des identifiants WoS des notices retournées (5 par défaut ou valeur de l’option “-n”) -j indique le nom du fichier qui recevra les cookies (“cookies.txt” paar défaut) -n indique le nombre de notices, entre 1 et 100, à retourner (5 par défaut) -t trie les résultats sur un champ (nom abrégé à 2 majuscules) de façon croissante (A) ou décroissante (D) ou par pertinence (RS) forcément décroissante EOT exit 0 } function nettoie { if [[ -f search$$.xml ]] then rm -f search$$.xml fi } # Déclaration explicite des tableaux “bases”, “champs” et “tri” declare -a bases declare -a champs #declare -a tri # Pour l’instant, on met un seul argument # Options while getopts b:f:hij:n:p:q:r:s:t: i do case $i in b) bases+=($OPTARG);; f) champs+=($OPTARG);; h) aide;; i) recid=1;; j) cookiejar=$OPTARG;; n) nrec=$OPTARG;; p) span=$OPTARG;; q) query=$OPTARG;; s) sid=$OPTARG;; # t) tri+=($OPTARG);; t) tri=$OPTARG;; \?) echo >&2 usage >&2 exit 1;; esac done # Vérification des options if [[ -z $sid || -z $query ]] then echo "Erreur : option(s) manquante(s)" >&2 echo "" >&2 usage >&2 echo "" exit 2 fi if [[ -z $cookiejar ]] then cookiejar='cookies.txt' fi if [[ ! $nrec ]] then nrec=5 else if [[ $nrec =~ ^[1-9][0-9]*$ ]] then if [[ $nrec -lt 1 || $nrec -gt 100 ]] then echo "Erreur : l’argument de l’option “-n” doit être un entier entre 1 et 100" >&2 exit 2 fi else echo "Erreur : l’argument de l’option “-n” doit être un entier entre 1 et 100" >&2 exit 2 fi fi # Vérification de la présence des programmes # “curl” et “xmllint” for i in curl xmllint do prog=$(which $i 2> /dev/null) if [[ -z $prog ]] then echo "" >&2 echo "Erreur : programme “$i” introuvable. Vérifier \$PATH." >&2 echo "" >&2 exit 2 fi done # Nettoyage en cas d’arrêt prématuré trap nettoie HUP INT QUIT TERM # Génération du fichier SOAP cat << EOT > search$$.xml <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:woksearch="http://woksearch.v3.wokmws.thomsonreuters.com"> <soapenv:Header/> <soapenv:Body> <woksearch:search> <queryParameters> <databaseId>WOS</databaseId> <userQuery>$query</userQuery> EOT # Cas de l’option “-b” # valeurs possibles : SCI, SSCI, AHCI, ISTP, ISSHP, IC, CCR, BSCI, BHCI et ESCI if [[ ${#bases[@]} -gt 0 ]] then for i in ${bases[@]} do if [[ $i =~ ^[A-Z]+:[A-Z]+$ ]] then coll=${i%:*} edit=${i#*:} else coll='WOS' edit=$i fi echo " <editions>" >> search$$.xml echo " <collection>$coll</collection>" >> search$$.xml echo " <edition>$edit</edition>" >> search$$.xml echo " </editions>" >> search$$.xml done fi if [[ -n $span ]] then regex="[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])" if [[ $span =~ ^$regex:$regex$ ]] then begin=${span%:*} end=${span#*:} # Vérification de la validité de chaque date for i in $begin $end do day=$(date -d $i 2> /dev/null) if [[ -z $day ]] then echo "" echo "Erreur : date “$i” invalide" >&2 nettoie exit 4 fi done echo " <timeSpan>" >> search$$.xml echo " <begin>$begin</begin>" >> search$$.xml echo " <end>$end</end>" >> search$$.xml echo " </timeSpan>" >> search$$.xml elif [[ $span =~ ^[124]week$ ]] then echo " <symbolicTimeSpan>$span</symbolicTimeSpan>" >> search$$.xml else echo "" echo "Erreur : argument incorrect pour l’option “-p”" >&2 nettoie exit 4 fi fi cat << EOT >> search$$.xml <queryLanguage>en</queryLanguage> </queryParameters> <retrieveParameters> <firstRecord>1</firstRecord> <count>$nrec</count> EOT # Cas de l'option “-t” # Valeurs possibles : AU, CF, CG, CW, CV, LC, LD, PG, PY, RS, SO, TC et VL # Valeurs possibles : (AU|CF|CG|CW|CV|LC|LD|PG|PY|RS|SO|TC|VL) if [[ -n $tri ]] then if [[ ! $tri =~ ^(AU|CF|CG|CW|CV|LC|LD|PG|PY|SO|VL):[AD]$ && ! $tri =~ ^(RS|TC):D$ ]] then echo "Erreur : argument incorrect pour pour l’option “-t”" >&2 exit 4 fi nom=${tri%%:*} sens=${tri#*:} echo " <sortField>" >> search$$.xml echo " <name>$nom</name>" >> search$$.xml echo " <sort>$sens</sort>" >> search$$.xml echo " </sortField>" >> search$$.xml fi # Cas de l’option “-f” # Valeurs possibles : UID, pub_info, names, full_name, titles, contributor, # language, doctypes, conf_title, conf_date, conf_host, conf_locations, sponsors, # keywords, keywords_plus, abstract, addresses, organizations, reprint_contact, # email_addr, grant, fund_text, refs, address_spec, headings, subjects, identifiers, # page, book_chapters et ids if [[ ${#champs[@]} -gt 0 ]] then ns='Fields' echo " <viewField>" >> search$$.xml echo " <collectionName>WOS</collectionName>" >> search$$.xml for item in ${champs[@]} do while [[ -n $item ]] do deb=${item%%,*} fin=${item#*,} echo " <fieldName>$deb</fieldName>" >> search$$.xml if [[ $deb = $fin ]] then item="" else item=$fin fi done done echo " </viewField>" >> search$$.xml else ns='FullRecord' fi if [[ $recid -gt 0 ]] then echo " <option>" >> search$$.xml echo " <key>RecordIDs</key>" >> search$$.xml echo " <value>On</value>" >> search$$.xml echo " </option>" >> search$$.xml fi cat << EOT >> search$$.xml <option> <key>targetNamespace</key> <value>http://scientific.thomsonreuters.com/schema/wok5.4/public/$ns</value> </option> </retrieveParameters> </woksearch:search> </soapenv:Body> </soapenv:Envelope> EOT out='WosApiOut.xml' err='WosApiErr.txt' curl -X POST -d @search$$.xml -b $cookiejar -c $cookiejar -v 'http://search.webofknowledge.com/esti/wokmws/ws/WokSearch?wsdl' \ -H "Cookie: SID=$sid" 2> $err | xmllint -format - > $out qid=$(perl -ne 'print "$1" if m|<queryId>(.+?)</queryId>|;' $out) if [[ -n $qid ]] then rec=$(perl -ne 'print "$1" if m|<recordsFound>(.+?)</recordsFound>|;' $out) max=$(perl -ne 'print "$1" if m|<recordsSearched>(.+?)</recordsSearched>|;' $out) echo " " echo "Numéro de requête (queryId) : $qid " if [[ $rec -gt 1 ]] then echo "$rec notices trouvées sur un total de $max notices " else echo "$rec notice trouvée sur un total de $max notices " fi echo " " else msg=$(perl -ne 'print "$1" if m|<faultstring>(.+?)</faultstring>|;' $out) if [[ -n $msg ]] then echo " " echo "Erreur : $msg " echo " " else echo " " echo "Erreur indéterminée. " echo "Voir fichier “$err”. " echo " " fi fi nettoie exit 0