Inviare dati da un form usando php bash ed Aruba

Per eseguire uno script php su hosting aruba che richiama uno script bash devi inserire lo script nella dir

/web/htdocs/www.recapriata.gov.it/home/cgi-bin/ciao.sh

Il codice dello script bash è (esegue la somma degli argomenti passati tramite form):

#!/bin/bash
a=$1
b=$2
echo ‘somma = ‘$((a+b))

exit 1

Il codice del pagine php che contiene il form è (pagina.php):

<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
<title>Add new customer </title>
</head>

<body>

<h1>Inserimento dati</h1>

<form method=”post” action=”web-add_new_customer.php”>

Primo numero: <br />
<input type=”text” name=”NUMERO_UNO” size=”35″ />
<br />

Secondo numero: <br />
<input type=”text” name=”NUMERO_DUE” size=”35″ />
<br /> <br />

<input type=”submit” value=”Invia” />
<br />
</form>

</body>
</html>

Il codice della script richiamato è (calcola_con_script_bash.php):

<?php
$NUMERO_UNO = $_POST[‘NUMERO_UNO’];
$NUMERO_DUE = $_POST[‘NUMERO_DUE’];

if(empty($NUMERO_UNO ) || empty($NUMERO_DUE )) {
echo “<h2>Compila tutti i campi</h2>\n” ;
die (“Torna indietro per compilare.”);
}

echo “<h2>Inserisci le informazioni necessarie:</h2>”;
echo “<b>Il primo numero inserito è:</b><br><br>”;
echo $NUMERO_UNO;
echo “<br><br><b>Il secondo numero inserito è:</b><br><br>”;
echo $NUMERO_DUE;
echo “<br><br/>”;
echo “<b>Comando:</b><br><br/>”;

$cmd = “/web/htdocs/www.dominiosito.it/home/cgi-bin/ciao.sh escapeshellarg($NUMERO_UNO) escapeshellarg($NUMERO_DUE)”;

echo(“Commando testuale = ” . $cmd . “<br/>\n”);
echo(“<b>Dump della variabile con var_dump</b><br/>\n”);
var_dump($cmd);

echo(“<br/>\n”);

exec(“/web/htdocs/www.dominiosito.it/home/cgi-bin/ciao.sh $NUMERO_UNO $NUMERO_DUE”, $output, $output2);

echo(“<br/>\n”);
echo(“Uscita array = ” . print_r($output) . “<br/>\n”);
echo(“Uscita = ” . $output2 . “<br/>\n”);
?>

Uscita array stampa l’array che contiene il risultato contenuta in $output

output2 contiene un valore numerico che segan se lo script è stato eseguito correttamente in questo caso restituisce 1 (vedi script bash)

 

 

 

 

Eseguire script bash su hosting linux Aruba

Ho avuto questa necessità…. come faccio?

Segue script bash hello.sh

#!/bin/bash
echo “Hello World!”

Segue script prova.php messo dentro la dir cgi-bin

<?php
$result=exec(“/web/htdocs/www.dominio.ext/home/cgi-bin/hello.sh”);
echo($result);
?>

I files vanno messi nella cartella cgi-bin con i permessi 0755 eseguire il tutto richizmando dal browser il file

https://www.dominio.ext/cgi-bin/prova.php

Vi faccio notare che lo script bash può essere richiamato anche passando dei parametri

<?php
$result=exec(“/web/htdocs/www.dominio.ext/home/cgi-bin/hello.sh abc bng”);
echo($result);
?>

Rendere PDF che contiene del testo inserito in una immagine ricercabile con Tesseract e script bash

A volte ci sono dei pdf che non sono ricercabili. Per permettere la ricerca di una parola o di una frase (anche con l’uso del mio script pubblicato in una altro link) ho trovato questo script chiamato pdfocr.sh

#! /bin/bash

INPUT=
declare -a INPUT_FILES
ARGUMENTS=( “$@” )
OUTPUT=
OUT_FINAL=
TESS_CONFIG=pdf
TESS_LANG=ita
RES=300
IMG_FMT=
MODE=full
TESS_PARAMS=
KEEP_TMP=false
MODE=full
PARALLEL=false
JOBS=1
GSDEV=jpeg
INPUT_BASENAME=
TMPDIR_PATH=~/tmp
VERBOSE=false

RESET=”\e[0m”
PENDING=”\e[1;91m”
ERROR=”\e[1;31m”
DONE=”\e[1;36m”
MSG=”\e[1;36m”

#regexes
shopt -s extglob

#kill child processes on error
trap ‘end_jobs’ EXIT

function pdfocr {

if [ ${#ARGUMENTS[@]} -eq 0 ]; then
print_usage
exit
fi

parse_args

check_req

for input_file in “${INPUT_FILES[@]}”; do
echo -e “${MSG}Input file:$RESET” `basename “$input_file”`

if [[ $MODE = clean ]]; then
echo Cleaning temp files…
fi

check_file “$input_file”

init “$input_file”

pdfocr_proc “$input_file”

echo

done

echo -e “${DONE}Finished$RESET”

}

function pdfocr_proc {

local input_file=$1

split “$input_file”

local IN_P=”$TMPDIR_PATH/$INPUT_BASENAME”

if [[ -n $PREPROCESSOR ]]; then
preprocess “$IN_P” “$IMG_FMT”
fi

ocr “$IN_P” “$IMG_FMT”

merge “$IN_P”

clean_tmp “$IN_P” “$IMG_FMT”
}

function split {

if ! [[ $MODE = @(full|split) ]];then
return
fi

echo -e ${PENDING}Running$RESET ghostscript

local IN_F=$1

local GS_OUT=”$TMPDIR_PATH/$INPUT_BASENAME%04d_gs.$IMG_FMT”
gs -dSAFER -dBATCH -dNOPAUSE -sDEVICE=$GSDEV -r$RES -dTextAlphaBits=4 \
-o “$GS_OUT” -f “$IN_F” > /dev/null

try “Error while converting $IN_F”
}

function preprocess {

if [ $PARALLEL = true ]; then
echo -e ${PENDING}Running$RESET preprocessor in parallel
export -f run_preproc
export -f try
local PRE4PARA=`parallel –shellquote ::: “$PREPROCESSOR”`
parallel -n 1 -d ::: -j $JOBS -m run_preproc “$PRE4PARA” {} ::: “$1″*_gs.”$2”
try “Error during parallel preprocessing!”
else
echo -e ${PENDING}Running$RESET preprocessor
for f in “$1″*_gs.”$2”;do
run_preproc “$PREPROCESSOR” “$f”
done
fi

}

function ocr {

if ! [[ $MODE = @(full|ocr) ]]; then
return
fi

local IN_P=”$TMPDIR_PATH/$INPUT_BASENAME”
if [ $PARALLEL = true ]; then
echo -e ${PENDING}Running$RESET tesseract in parallel
if [ “$VERBOSE” = false ];then
run_wait
fi

export -f run_tess
export -f try
export -f print_errors

if [ -z “$TESS_PARAMS” ]; then
TESS_PARAMS=” ”
fi

local ESC=`echo $TESS_PARAMS| sed ‘s/-/__-/’`
ESC=`parallel –shellquote ::: “$ESC”`
parallel -n1 -j $JOBS -m run_tess {} “$TESS_LANG” “$ESC” “$TESS_CONFIG” “$VERBOSE” ::: “$1″*_gs.”$2”
try “Error while running parallel tesseract jobs!”

if [ “$VERBOSE” = false ]; then
kill -INT $!
fi

else
echo -e ${PENDING}Running$RESET tesseract
if [ “$VERBOSE” = false ];then
run_wait
fi

for f in “$1″*_gs.”$2”; do
run_tess “$f” “$TESS_LANG” “$TESS_PARAMS” “$TESS_CONFIG” “$VERBOSE”
done

if [ “$VERBOSE” = false ]; then
kill -INT $!
fi
fi
}

function merge {

if ! [[ $MODE = @(full|merge) ]]; then
return
fi

# local IN_P=”$TMPDIR_PATH/$INPUT_BASENAME”
local file_count=`ls -1 “$1″*_gs_tess.pdf | wc -l`
echo -e ${PENDING}Merging$RESET into $OUT_FINAL
if [[ $file_count -gt 1 ]]; then
pdfunite “$1″*_gs_tess.pdf “$OUT_FINAL”
else
cp “$1″*_gs_tess.pdf “$OUT_FINAL”
fi
try “Error while merging $1″*”$2 into $OUT_FINAL”
}

function clean_tmp {
if [ $KEEP_TMP = true ]; then
return
fi

if [[ $MODE != split ]]; then
rm “$1″*_gs.”$2”
fi
if [[ $MODE != ocr ]]; then
rm “$1″*_gs_tess.pdf
fi
}
function run_wait {

export -f wait_anim
wait_anim &

}

function run_tess {
local IN=$1
local TESS_LANG=$2
local TESS_PARAMS=$3
TESS_PARAMS=`echo $TESS_PARAMS | sed ‘s/__-/-/’`
local TESS_CONFIG=$4
local VERBOSE=$5
local tess_o=
if [ “$VERBOSE” = true ]; then
echo tesseract “$IN” “${IN%.*}_tess” -l $TESS_LANG -psm 3 $TESS_PARAMS $TESS_CONFIG
fi

tess_o=$(tesseract “$IN” “${IN%.*}_tess” -l $TESS_LANG -psm 3 $TESS_PARAMS $TESS_CONFIG 2>&1)
try “Error while performing ocr!” “$tess_o”

if [ “$VERBOSE” = true ]; then
echo $tess_o
echo Tesseract input $1
echo Tesseract output ${1%.*}_tess.pdf
fi
}

function run_preproc {
local PAGE_NUM=`echo $2|gawk ‘match($0,/.+([0-9]{4})_gs.*/,arr) { print arr[1]}’`
$1 “$2” $PAGE_NUM
try “Error while preprocessing!” “Preprocessor: $1” “Input file: $2”
}

function init {

local INPUT=$1

INPUT_BASENAME=$(basename “$INPUT”)
INPUT_BASENAME=${INPUT_BASENAME%.*}

if [ -z “$OUTPUT” ]; then

local INPUT_DIR=$(dirname “$INPUT”)
OUT_FINAL=”$INPUT_DIR/$INPUT_BASENAME”_ocr.pdf

else

if [[ “$OUTPUT” =~ INPUT_BASENAME ]]; then
OUT_FINAL=”${OUTPUT/INPUT_BASENAME/$INPUT_BASENAME}”
elif [[ “${OUTPUT: -1}” == “/” ]]; then
OUT_FINAL=”$OUTPUT$INPUT_BASENAME”_ocr.pdf
OUTPUT_DIR=$OUTPUT
else
OUT_FINAL=$OUTPUT
fi

if [ -z $OUTPUT_DIR ]; then
local OUTPUT_DIR=$(dirname $OUTPUT)
fi

if [ ! -d “$OUTPUT_DIR” ]; then
mkdir -p “$OUTPUT_DIR”
try “Failed creating the output directory: $OUTPUT_DIR”
fi

fi

if [ ! -d “TMPDIR_PATH” ]; then
mkdir -p “$TMPDIR_PATH”
try “Failed creating the temporary directory: $TMPDIR_PATH”
fi

case $GSDEV in
jpeg)
IMG_FMT=jpg
;;
ppm)
;;
png*)
IMG_FMT=png
;;
tiff*)
IMG_FMT=tiff
;;
*)
throw “$IMG_FMT not supported”
;;
esac
}

function parse_args {

local let in_c=0
local let v_c=0

local LANGS_ARR=()
local IN_ARG=

while [[ $v_c -lt ${#ARGUMENTS[@]} ]]; do

key=${ARGUMENTS[$v_c]}

if (( v_c < ${#ARGUMENTS[@]} ));then
local val=”${ARGUMENTS[$((v_c+1))]}”
if [[ $val == -* ]]; then
val=
fi

fi
case $key in
-*)
IN_ARG=
let in_c=0
;;&
-i|–input)
IN_ARG=INPUT
;;
-o|–output)
OUTPUT=”$val”
;;
-t|–tempdir)
TMPDIR_PATH=”$val”
;;
–tess-config)
TESS_CONFIG=”$val”
;;
-l|–language)
IN_ARG=TESS_LANG
;;
-r|–resolution)
RES=”$val”
;;
-f|–img-format)
GSDEV=”$val”
;;
-c|–tess-param)
TESS_PARAMS=”$TESS_PARAMS -c $val”
;;
–keep-tmp)
KEEP_TMP=true
;;
-m|–mode)
MODE=”$val”
;;
-p|–parallel)
if hash parallel 2>/dev/null; then
PARALLEL=true
if [[ -n $val ]]; then
JOBS=$val
else
JOBS=`parallel –number-of-cores`
fi
fi
;;
-s|–preprocessor)
PREPROCESSOR=$val
;;
-v|–verbose)
VERBOSE=true
;;
-h|–help)
print_help
exit
;;
*)
case $IN_ARG in
INPUT)
INPUT_FILES[$in_c]=$key
let in_c++
;;
TESS_LANG)
LANGS_ARR[$in_c]=$key
let in_c++
esac
;;
esac
let v_c++
done

if [[ ${#LANGS_ARR} -gt 0 ]]; then
TESS_LANG=”${LANGS_ARR[@]}”
TESS_LANG=`echo “$TESS_LANG”|sed ‘s/ /+/’`
fi

if ! [[ $MODE = @(split|full|ocr|merge|clean) ]];then
echo “Invalid mode: $MODE”
print_usage
exit
fi

}

function check_req {

if ! hash pdfunite 2> /dev/null; then
throw “pdfunite missing!”
fi

if ! hash tesseract 2> /dev/null; then
throw “tesseract missing!”
fi

if ! hash gs 2> /dev/null; then
throw “ghostscript missing!”
fi

if [ ${#INPUT_FILES[@]} -eq 0 ]; then
throw “pdf input path is missing!”
fi
}

function check_file {
if ! [ -f “$1” ]; then
throw “No such file: $1”
fi
}

function try {
if [[ $? -ne 0 ]] ; then
throw “$@”
fi
return 0
}

function throw {
print_errors “$@”
exit 1
}

function print_errors {
for msg; do
echo -e “$ERROR$msg$RESET”
done
}

function print_help {

cat << END
pdfocr script

Description:

A convenience script that implements a pipeline for creating a searchable
pdf file. The pipeline involves three parts:
-pdf splitting and conversion to images
-character recognition
-merging into the final pdf
Each step can be performed separately of others. You can split pdf, preprocess
images (e.g. with ImageMagick) and then perform ocr and merging.

Requirements:

The following software applications are required:
gs (Ghostscript)
tesseract
pdfunite

Optional:
parallel (speeds up ocr on multiple cores)

Usage:

pdfocr -i|–input input.pdf [options…]

Options:

-l, –lang LANGS set the language(s) for tesseract; check available
languages with:
tesseract –list-langs

-o, –output OUTPUT_PATH set the output path; it can be explicit or use the
INPUT_BASENAME variable to construct it dynamically
e.g. , -o INPUT_BASENAME_ocr.pdf
Default: INPUT_BASENAME_ocr.pdf

-t, –tempdir TMPDIR_PATH set the path to directory with intermediate
files; Default: ~/tmp

-s, –preprocessor PROC_PATH set the path to an image preprocessor;
the preprocessor shall be executed for the image of
each page like this:
preprocessor img_path page_num
the preprocessor should overwrite the original image

-m, –mode MODE set the mode to perform only the part of processing;
MODE can be one of:
split
ocr
merge
full
Default: full
note: it is assumed that required files are in the
TMPDIR_PATH; modes ‘split’ and ‘ocr’ don’t delete
their output intermediate files

–tess-config CONFIG set the tesseract configuration; default: pdf

-p, –parallel [JOBS] use GNU parallel if available; limit the number
of jobs to JOBS

-v, –verbose allow verbose output

–keep-tmp keep the intermediate files; deleted by default

-f, –img-format the format of the intermediate images;
possible values:
jpeg png* ppm tiff*
any format supported by Ghostscript that matches
the above values is valid;
note: the image format makes a difference for
tesseract, so experiment with different values
Default: jpeg

-r, –resolution RES set the resolution of intermediate images to RES;
default: 300

-c, –tess-param key=val set a tesseract parameter
e.g., -c textord_min_linesize=2.5

-h, –help print this
END
}

function print_usage {
cat << END
pdfocr script

Usage:

pdfocr -i|–input input.pdf [options…]

Options:

-h, –help print help
-l, –lang LANGS set the language(s) for tesseract
-o, –output OUTPUT_PATH set the output path
-t, –tempdir TMPDIR_PATH set the path to tempdir (def: ~/tmp)
-m, –mode MODE set the mode (split,ocr,merge,full)
–tess-config CONFIG set the tesseract configuration; default: pdf
-f, –img-format FMT the format of the intermediate images;
jpeg png* ppm tiff*
-r, –resolution NUM set the resolution of the intermediate images
-c, –tess-param key=val set a tesseract parameter
–keep-tmp keep the intermediate files; deleted by default
-p, –parallel [JOBS] use GNU parallel if available
-v, –verbose allow verbose output
-s, –preprocessor PROC_PATH set the path to images preprocessor

END

}

function wait_anim {

trap “__STOP_PRINT=true” SIGINT
local move=r
local let length=5
local let pos=0
while [[ $__STOP_PRINT != true ]]; do

echo -en ” |”

for ((i=0;i<pos;i++));do
echo -n ” ”
done

echo -en “$PENDING*$RESET”

for ((i=0;i<length-pos;i++));do
echo -n ” ”
done

echo -en “|”
echo -ne \\r
if [[ $move == r ]]; then
let pos++
if ((pos>=length)); then
move=l
fi
else
let pos–
if ((pos<=0)); then
move=r
fi
fi

sleep 0.07
done
}

function end_jobs {

local job_n=`jobs -p | wc -l`
if ((job_n>0)); then
jobs -p | xargs kill
fi

}

pdfocr
trap ” EXIT SIGINT

# vim: ts=2 sw=2

Cambiare versione PHP Aruba.it

Da qualche mese Aruba ha aggiornato il look del Pannello di Controllo. Sicuramente più compatto rispetto al precedente paginone, questo cambio ha causato diversi disagi a determinati utenti, che non riuscirebbero più a trovare delle funzioni. Più che di difficoltà però, si tratta di disabitudine: abbandonare un’interfaccia usata per anni e anni (magari quotidianamente) non è certo facile.

Il dilemma di oggi è: dove posso modificare la versione di PHP in uso? Riferito al servizio Hosting, quindi siti web. Aruba offre un semplice tool per farlo, ma sembra essersi perso. In realtà, raggiungerlo è semplice!

Ci basta effettuare il Login, e cliccare poi su Pannello di Controllo. Sulla colonna dei menù a sinistra, clicchiamo su Hosting Linux, e poi sulla sottovoce Gestione Hosting Linux. Verremo reindirizzati ad un’altra pagina, dove ci basterà cliccare sul tab Strumenti e Impostazioni (in alto), e da li cliccare su Scelta della versione PHP. Aperto il pop-up, scegliamo la versione desiderata e confermiamo. Nel giro di qualche minuto, saremo in grado di verificare la nuova versione di PHP.

Problemi di compatibilità sconfitti in meno di un minuto 😎

PDF Estrattore di testo e di pagine script bash

Lo script estrae del testo da alcuni file pdf inseriti in una dir passata come argomento e li copia in una cartella deposito di un percorso specificato. Vengono creati dei file pdf con le pagine che contengono le stringe ricercate oltre a copiare il file originale. Se il nome del file contiene degli spazi questi vengono sostituiti con il carattere undescore “_”.

pdfestrattore.sh “Text” “./target/*” “./destination/”

#!/bin/bash
# Ricerca Testo e copia file presso la directory di destinazione
# bash pdfestrattore.sh “Text” “./target/*” “./destination/”
#  Vers. 1.1 del 06/02/2017
# Uso del pdfgrep versione 1.4.x e 2.0.x

controllapdfgrep=(`which pdfgrep`)
controllapdftk=(`which pdftk`)

if [ “$controllapdfgrep” = “” ];
then
echo “PdfGrep non è installato! Il comando su Ubuntu è apt-get install pdfgrep”
exit
fi

if [ “$controllapdftk” = “” ];
then
echo “Pdftk non è installato! Il comando su Ubuntu è  apt-get install pdftk”
exit
fi

function pausa()
{
read -p “$*”
}

#funzione usata per rinominare i file
RINOMINAFILE() {
#$FILE non è necessario definirla come locale
local BASENAME=$1 #$1 è la 1° variabile passata alla funzione al momento della sua invocazione
#se non ho spazi nel nome file non lo devo rinominare
if echo $BASENAME | grep ” ” ; then
NUOVONOMEFILE=`echo $BASENAME | tr ‘A-Z ‘ ‘A-Z_’`
#rinomino il file $NUOVONOMEFILE contiene il nome del file
#con gli spazi traformati in _
mv “$BASENAME” $NUOVONOMEFILE
fi
}

#questa è una funzione ricorsiva
RINOMINADIR() {
#$DIR è necessario definirla come locale
local DIR=$1
if echo $DIR | grep ” ” ; then
NUOVONOMEDIR=`echo $DIR | tr ‘A-Z ‘ ‘A-Z_’`
mv “$DIR” $NUOVONOMEDIR
else
#se non ci sono spazi assegno a $NUOVONOMEDIR il valor di $DIR
NUOVONOMEDIR=$DIR
fi
#Entro nella dir per verificare se ho altre dir o file
cd $NUOVONOMEDIR
find -maxdepth 1 | while read d; do
#il comando find mi restituisce tra i risultati anche la dir corrente ./
#che non và considerata
if [ “$d” != “.” ]; then
#verifico se $d è una directory
if [ -d “$d” ]; then
#se $d è una directory richiamo la funzione ricorsivamente
RINOMINADIR “$d”
else
#se $d non è una directory richiamo la funzione RINOMINAFILE
RINOMINAFILE “$d”
fi
fi
done
#Visto che prima sono entrato in $NUOVONOMEDIR adesso devo uscirne per poter continuare
cd ..
}

#MAIN
find -maxdepth 1 | while read l; do
#il comando find mi restituisce tra i risultati anche la dir corrente ./
#che non và considerata
if [ “$l” != “.” ]; then
#verifico se ho una directory
if [ -d “$l” ]; then
#ricchiamo la funzione RINOMINADIR
RINOMINADIR “$l”
else
#ricchiamo la funzione RINOMINAFILE
RINOMINAFILE “$l”
fi
fi
done

# Controlla se il comando viene eseguito con le opzioni corrette

if [ $# -eq 0 ]; then
echo -e ” ”
echo -e “pdfestrattore.sh Script v. 1.0 del 31-01-2017″
echo -e ” ”
echo -e “SINTASSI: ./pdfestrattore.sh “Text da cercare” sorgente destinazione”
echo -e ” ”
echo -e “Errore: devi specificare degli argomenti!”
echo -e ” ”
exit 1;
fi

PERCORSO=”$3″
ARCHIVIO=”deposito”

# Controlla l’esistenza della dir e cancella il contenuto, se non presente crea sotto $DESTINAZIONE la cartella deposito
if [ ! -d $PERCORSO/$ARCHIVIO ]; then
echo -e “Verra’ creata la dir $PERCORSO/$ARCHIVIO!”
#  chiamata di funzione pausa
pausa ‘Premere [Enter] per continuare, puoi premere CTRL+C per interrompere!’
mkdir -p $PERCORSO/$ARCHIVIO;
else
echo -e “Attenzione i file della dir $PERCORSO/$ARCHIVIO verranno cancellati!”
# controlla il numero di file nella directori di origine e di destinazione
NUMERO1=`ls -l “$2” | wc -l`
echo -e “Il numbero di files nella cartella di origine è $NUMERO1”
NUMERO2=`ls -l “$3” | wc -l`
echo -e “Il numbero di files nella catella di destinazione è $NUMERO2″
#  chiamata di funzione pausa
pausa ‘Premere [Enter] per continuare, puoi premere CTRL+C per interrompere!’
rm -rf $PERCORSO/$ARCHIVIO/*;
fi;

while read line; do
file=$(echo $line|awk -F: ‘{print $1}’)
STRING=”$1″
FILENAME=”${file##*/}”
BASENAME=”${FILENAME%.*}”
DIRNAME=”${file%/*}”
printf “$file: ”
echo “$line”|grep -q :0$ && echo Stringa non trovata! && continue
echo Stringa trovata!
cp -fi “$file” $PERCORSO/$ARCHIVIO;
RINOMINAFILE “${PERCORSO}/${ARCHIVIO}/${BASENAME}.pdf”
echo “Salvataggio nella dir: $PERCORSO/$ARCHIVIO del file completo: ${FILENAME}”
echo “Processo il file: $FILENAME…”
echo “Sto controllando per la stringa: $STRING…”
echo “Salvataggio nella dir: $PERCORSO/$ARCHIVIO del file ${BASENAME}_pagina_con_${STRING}.pdf”
## Ricerca il testo nei file passati
PAGES=”$(pdfgrep -in “$STRING” “$file” | cut -f1 -d “:” | uniq | tr ‘\n’ ‘ ‘)”
echo “Trovata stringa nella/e pagina/e numero: $PAGES”
## extract pages to new file in original directory
echo “Sto estraendo le pagine…”
pdftk “$file” cat $PAGES output “${PERCORSO}/${ARCHIVIO}/${BASENAME}_pagina_con_${STRING}.pdf”
RINOMINAFILE “${PERCORSO}/${ARCHIVIO}/${BASENAME}_pagina_con_${STRING}.pdf”
echo “Ciclo terminato per il file ${FILENAME}”
done < <(find $2 -type f -iname ‘*.pdf’ -exec pdfgrep -ircnHF “${STRING}” {} \;)
echo “Programma terminato!”

 

Opzioni da linea di comando con getopts

Nei miei script di studio, per il passaggio di dati agli script, fino ad ora, ho utilizzato i parametri posizionali ($1, $2,…${N}); è ora di imparare ad usare degli indici letterali come negli script “seri” del tipo:

nomescript -a parametro -b altro Parametro.

Per fare quello che voglio, ho trovato due possibili comandi: “getopts” e “getopt”; il primo, a differenza del secondo, non ammette l’uso di “stringhe opzione lunghe” (–opzione) ma solo ad un carattere (-a), ma ha il vantaggio di essere un “builtin” quindi presente di default in Bash; per questo motivo parlerò di “getopts”.

Ho fatto un piccolo script per le prove (più in basso) e mi segnerò su questa pagina qualche annotazione utile sull’uso del comando.

USO di base

Per prima cosa vanno decise le lettere da usare come opzioni letterali nel mio caso ‘a, b, c, d, e, h’ nell’utilizzo sulla linea di comando devono essere precedute dal “-” (meno) ed inserite singolarmente (non: ‘script -abc’ ma ‘script -a -b -c’ ).

Per l’utilizzo pratico conviene inserirle in un ciclo while con case, vedere lo script ed i commenti:

#!/bin/bash
clear script=$(basename $0)
help=”Questo script, ‘$script’, serve solo per vedere l’uso di getopts quindi affinché venga eseguito correttamente occorre passare almeno un’opzione. Le opzioni accettate sono: ‘-a’, ‘-b’, ‘-c’, ‘-d’, ‘-e’ e ‘-h’
Le opzioni ‘a,b,c,d,e’ mostrano solo l’opzione passata ed il proprio eventuale argomento. L’opzione ‘-h’ mostra l’help Solo ‘-c’ accetta un argomento, da passare da linea di comando, dopo l’opzione. Il ‘-‘ (meno) identifica, nella lettera che segue, un’opzione.\n Es.:./opzioni_prova.sh -a -b -c prova -d -e -h
# Controllo che sia stato passato almeno un argomento
if [ $# -eq 0 ] # se lo script è eseguito senza argomenti…
then
echo -e “$help” # … stampo l’help…
exit 1 # … ed esco.
fi
while getopts “:abc:deh” opzione # Dichiaro le opzioni accettate e il tipo
# i ‘:’ (due punti) iniziali sopprimono i messaggi di errore
# i ‘:’ (due punti) dopo un’opzione significano che ci si aspetta un argomento.
# Occhio! Qualsiasi cosa dopo ‘-c’ viene preso come argomento di ‘-c’
do
case $opzione in
# $OPTIND è il puntatore (numerico) all’opzione successiva
# $OPTARG è l’argomento passato, se esiste
a ) echo -e “\nhai inserito l’opzione -a con \$OPTIND: $OPTIND e argomento: $OPTARG”;;
b ) echo -e “\nhai inserito l’opzione -b con \$OPTIND: $OPTIND e argomento: $OPTARG”;;
c ) echo -e “\nhai inserito l’opzione -c con \$OPTIND: $OPTIND e argomento: $OPTARG”;;
d ) echo -e “\nhai inserito l’opzione -d con \$OPTIND: $OPTIND e argomento: $OPTARG”;;
e ) echo -e “\nhai inserito l’opzione -e con \$OPTIND: $OPTIND e argomento: $OPTARG”;;
h ) echo -e “\n$help”;; * ) echo -e “\nÈ stata inserita un’opzione non valida.\n\n $help”;;
esac
done shift $(($OPTIND – 1)) # resetto (come $OPTIND=1)
# Sposta il puntatore all’opzione che segue per esempio il parametro posizionale $1.
exit 0

Nella riga while getopts “:abc:deh” Opzione i primi : (due punti) servono per utilizzare il comando in modalità silenziosa, sopprimendo gli eventuali messaggi di errore.

I : (due punti) posti dopo la lettera c servono ad indicare che l’opzione -c accetta un parametro obbligatorio, se il parametro non viene inserito verrà preso come parametro qualsiasi stringa seguente -c quindi attenzione!

Nella stessa riga, la stringa “opzione” è la variabile impostata dal ciclo while che verrà utilizzata nel costrutto case.
Le righe in case sono quasi tutte del tipo:

a ) echo -e “\nhai inserito l’opzione -a con \$OPTIND: $OPTIND e argomento: $OPTARG”;;
servono solo per mostrare i valori dell’opzione passata, il valore di $OPTIND (che è l’indice numerico dell’opzione successiva) e dell’eventuale valore del parametro passato, contenuto in $OPTARG.
La riga:
h ) echo -e “\n$help”;;
a differenza delle precedenti stampa a video solo quanto scritto nella variabile $help.
La riga:
* ) echo -e “\nÈ stata inserita un’opzione non valida.\n\n $help”;;
intercetta tutto quanto è diverso dalle opzioni indicate precedentemente, quindi le opzioni non valide, informa del fatto e mostra l’help.
La riga:
shift $(($OPTIND – 1))
serve a “resettare” $OPTIND equivale a $OPTIND=1. Dopo aver resettato si potrebbero usare gli eventuali parametri posizionali o anche ripetere il ciclo precedente

Le prove

Conviene scaricare lo script opzioni_prova.sh renderlo eseguibile e provarlo; inizialmente in modo corretto con: ./opzioni_prova.sh -a -b -c prova -d -e -h in seguito conviene provare a passare dati incompleti, con parametro e senza, sbagliati etc. si comprenderà facilmente la forza ed i limiti del comando.

Ricercare i pdf e nei pdf

Un amico mi chiese una applicazione per poter cercare nei pdf….. 2 soluzioni

a) recoll http://www.lesbonscomptes.com/recoll/download.html#general

b) pdfgrep https://gitlab.com/pdfgrep/pdfgrep

presenti sia sotto linux che sotto windows.

Lo script per estrarre pagine pdf da un file pdf piu’ grande il file si chiama pdfselect.sh

#!/bin/bash
# extract pages from a big pdf file using gs
# Usage:
#           pdfselect.sh pdffile startPageNumber endPageNumber

function getPDFPages()
{
if [ -e $1 ]; then
pdfinfo $1 | grep Pages | awk {print $2}
else
echo 0;
fi
}

if [ $# -lt 2 ]; then
sed -n 3,4p `which pdfselect.sh`
exit
fi

oriPdf=$1
[ ! -e ${oriPdf} ] && echo ${oriPdf} does not exist! && exit

numPage=`getPDFPages ${oriPdf}`
[ ${numPage} -eq 0 ] && ZERO page is found in ${oriPdf} && exit

sPage=$2
[ ${sPage} -gt ${numPage} ] && ${sPage}=${numPage}
i

———————- SCRIPT FILE ESTRATTORE DI PAGINE DA FILE PDF IN BASE ALLA RICERCA ——

# ./extract_pdf_results.sh Lagrange ./test.pdf
# ./extract_pdf_results.sh “Text” $file

STRING=”$1″
FILE=”$2″
FILENAME=”${FILE##*/})”
BASENAME=”${FILENAME%.*}”
DIRNAME=”${FILE%/*}”

echo “Processing $FILE…”

## find pages that contain string, remove duplicates, convert newlines to spaces

echo “Looking for $STRING…”

PAGES=”$(pdfgrep -n “$STRING” “$FILE” | cut -f1 -d “:” | uniq | tr ‘\n’ ‘ ‘)”

echo “Matching pages:
$PAGES”

## extract pages to new file in original directory

echo “Extracting result pages…”

pdftk “$FILE” cat $PAGES output “${DIRNAME}/${BASENAME}_pages_with_${STRING}.pdf”

echo “Done.”

—— SCRIPT CHE COPIA FILE PDF CHE CONTENGONO STRINGA IN UNA OPPORTUNA DIR —

#!/bin/bash
# Ricerca Testo e copia file presso la directory di destinazione
# bash pdfgrepandmv.sh “Text” “./target/*” “./destination/”

while read line; do
file=$(echo $line|awk -F: ‘{print $1}’)
printf “$file: ”
echo “$line”|grep -q :0$ && echo STRINGA NON TROVATA! && continue
echo STRINGA TROVATA
cp -i “$file” $3
done < <(find $2 -type f -iname ‘*.pdf’ -exec pdfgrep -Hc “$1” {} \;)