[>a2448.html>] [<a2446.html<] [^a2.html^]
Come, mai se faccio uno script stupidissimo come questo:
#!/bin/sh cd /home/aur
e lo avvio, non mi va alla directory /home/aur
?
---------
Perché lo script viene eseguito da una shell secondaria (/bin/sh
), che termina quando finisce lo script e pertanto perde tutte le impostazioni (compresa PWD, cioè la directory corrente). Per farlo eseguire dalla shell principale (cioè quella che accetta i tuoi comandi) dovresti creare un alias, una funzione oppure fare:
$
source nomescript
[Invio]
o:
$
. nomescript
[Invio]
in questo caso infatti sarà la shell corrente ad eseguire i comandi e non un processo figlio.
---------
Certo, dagli l'estensione .cgi, forniscigli i permessi con:
#
chmod 755 file.cgi
[Invio]
e richiamalo mediante link o fornendo l'indirizzo esatto. Come cgi puoi usare qualunque linguaggio interpretato o compilato che sia in grado di leggere lo standard input, scrivere su standard output e leggere il contenuto delle variabili d'ambiente.
Esiste un comando o un sistema per contare i caratteri presenti in un file di testo?
---------
$
cat nomefile | wc -l
[Invio]
conta le linee;
$
cat nomefile | wc -c
[Invio]
conta i caratteri;
$
man wc
[Invio]
per dettagli.
Non ho capito la differenza tra il parametro posizionale $@ e $#. Chi me li spiega?
---------
Scrivi questo file: prova.sh
#!/bin/bash echo $@; echo $#;
Ora, dopo avergli dato i permessi di esecuzione, prova a lanciarlo in questo modo:
$
./prova.sh ciao bla "un esempio"
[Invio]
Penso che ti sarà molto chiaro il risultato.
$@ stamperà tutti i parametri passati da linea di comando, mentre $# indicherà la posizione dell'ultimo di essi, nel nostro caso 3.
Aggiungi allo script anche la riga:
echo $3
Come puoi vedere, verrà restituito un esempio.
Come si aggiungono i numeri di riga ad un file di testo? Mi serve di numerare progressivamente tutte le righe di un file.
---------
Lo puoi fare con perl. Crea un file pippo.pl
e rendilo eseguibile:
#!/usr/bin/perl $nr=0; while (<STDIN>){ # Cambia eventualmente %04d con quello che vuoi print sprintf("%04d: %s",$nr,$_); $nr++; } exit;
e poi dai il comando:
$
cat pluto.txt | ./pippo.pl > filenumerato
[Invio]
Mi chiedevo se esiste già o se è possibile realizzare un comando che esegua il seguente compito:
comando percorso_directory_scelta
con un output costituito da un file a caso (senza tutto il percorso) contenuto nella directory_scelta.
---------
$
ls -1 | sed -e $(random -e `ls -1 | wc -l` ; echo $(( RAND=$?+1 )))p --quiet
[Invio]
Possiamo sopperire alla mancanza di 'random' con l'equivalente in perl:
$
perl -e '@files=`ls -1`;print "@files[int(rand($#files))]\n";'
[Invio]
Ho la necessità di cercare in una directory e nelle relative discendenti, se ci sono o meno dei file con nomi uguali e che il risultato di questa ricerca venga poi inviato ad un file di testo
---------
------ #!/bin/sh # $1= directory dove cercare i file. for $i in `find $1 -name *`; do $n= basename $i if [ `find $1 -name $n |wc -l` -gt 1]; then find $1 -name $n fi done ------
Forse un po' lento ma dovrebbe andare. Per mettere l'output in un file di testo basta redirigere l'output con un '>'.
Oppure:
$
for F in `ls -1 -R percorso_dir1`; do find percorso_dir2 -name $F; done > lista_files_doppi
[Invio]
dove per percorso_dir1 si intende il percorso completo della prima directory da confrontare, e per percorso_dir2 il percorso della seconda, analogamente.
Come si può creare uno script che mi rinomini in minuscolo tutti i file di una directory? Oppure esiste già un comando apposito?
---------
$
perl -e '@files = `ls -1`; chop @files; foreach $f(@files){!-e lc($f) && rename ($f, lc($f))}'
[Invio]
o con la shell:
$
for FILE in `/bin/ls`; do FILELOWER=`echo $FILE | tr A-Z a-z`; mv -i $FILE $FILELOWER; done
[Invio]
Ho ricevuto dei file di dati (.txt) in cui gli stessi sono ordinati (con la data ad inizio riga) cronologicamente dal più recente al più vecchio. Mi servono al contrario. In pratica la prima riga deve diventare l'ultima; la seconda la penultima, ecc..
---------
$
cat -n nome_file | sort -r | awk '{$1="";print}' | sed -e s/\ // > nuovo_file
[Invio]
oppure:
$
cat nome_file | perl -e '@a=< STDIN >; while(@a){print pop(@a)};' > nuovo_file
[Invio]
Non basta il semplice:
$
cat nome_file | sort -r > nome_file.rev
[Invio]
che funzionerebbe se il primo campo di ogni riga fosse la data in formato aa/mm/gg. Ma se è invece in formato gg/mm/aa le righe verrebbero ordinate in base al giorno e non in base all'anno.
Vorrei sostituire da una frase una parola con un'altra. Come si fa?
---------
Con il comando sed, eccoti un esempio:
$
echo 'Il miglior sistema operativo: Windows' | sed /Windows/s//Linux/g
[Invio]
Come si fa a sapere quante volte compare una parola in un file?
---------
$
grep parola file|wc -l
[Invio]
Molto spesso negli script che contengono if compare l'opzione -f. Cosa sta ad indicare?
---------
Credo che tu intenda questo:
#!/bin/bash if [ -f "$1" ]; then echo "file regolare"; fi
Se il percorso passato come argomento a questo script rappresenta un file regolare, lo script te lo segnala. Per file regolare si intende un qualsiasi file normale, che non sia quindi un dispositivo, un socket, una directory, ecc.
In alcuni script shell mi interessa utilizzare la data. Digitando però:
$
date
[Invio]
mi vengono restituite informazioni inutili e fastidiose per il mio script. Come posso eliminarle?
---------
Il comando:
$
echo `date +%x`
[Invio]
ti restituisce il formato: mm/gg/aa. Utilizzare invece:
$
echo `date +%x` | sed "/\//s///g"
[Invio]
ti potrebbe essere più utile in quanto restituisce il formato: mmggaa.
Le virgolette nell'ultimo comando sono necessarie a causa della '\'. Lo stesso risultato lo ottieni con:
$
echo `date +%x | sed 's/\///g'`
[Invio]
Vorrei che nel file pippo.txt
tutte le stringa fossero sostituite da stringa1. Quale è il comando?
---------
Eccolo:
$
sed s/'stringa'/'stringa1'/g pippo.txt > filemodificato.txt
[Invio]
Come faccio a cercare tutti i file di un certo tipo (*.png) e a copiarli in una directory?
---------
Se la directory di destinazione è /root/pngfile
:
#
find / -name "*.png" -exec cp -p {} /root/pngfile \;
[Invio]
Come si può creare uno script che mi permetta di cambiare solo le estensioni di gruppi di file?
---------
#!/usr/bin/perl $old_ext = @ARGV[0] || usage(); $new_ext = @ARGV[1] || usage(); print "$old_ext --> $new_ext\n\n"; @files = `ls -1`; chop @files; foreach $f(@files) { $f =~ /(^.*)\.$old_ext/ && rename ($f, "$1.$new_ext"); } sub usage { print <<"END"; Usage: ./script.pl old_ext new_ext Example: ./script.pl tar.gz zip END exit(1); }
Dai i permessi di esecuzione e invocalo nella directory in cui devi rinominare i files.
Siccome lo script per semplicità non effettua alcun controllo sulla nuova estensione richiesta dall'utente, è meglio usarlo con prudenza.
$
pppstats -r -v ppp0
[Invio]
ottengo qualcosa tipo:
IN PACK VJCOMP VJTOSS NON-VJ RATIO UBYTE | OUT PACK VJCOMP VJSRCH VJMISS RATIO UBYTE 48089 366 16 0 99 1.00 0 | 308840 385 54 212 8 1.00 0
vorrei togliere la prima riga e avere la seconda tale e quale, ma tra un numero e l'altro non ci devono essere gli spazi ma dei caratteri di tabulazione.
---------
Ecco i comandi necessari:
#
pppstats -r -v ppp0 | grep -v VJCOMP | perl -e '$i=<STDIN>;$i=~s/\s+/\t/g;print $i;' | cut -f 2-
[Invio]
#
perl -e '@a=split(/\s+/, `pppstats -r -v ppp0|grep -v VJCOMP`);shift(a);foreach $b(@a) {print "$b\t"};'
[Invio]
#
pppstats -r -v ppp0 | grep -v OUT | sed -e 's/\ \+/ /g' | cut -f 2-
[Invio]
(N.B.: nella parte con il sed il tab è scritto con [Ctrl+v] e [tab])
Esiste un modo per rimpiazzare da riga di comando alcuni caratteri contenuti in un file di testo con altri caratteri? In sostanza, mi serve un modo per convertire tutti i «<» contenuti in un file in «:»
---------
$
sed -e s/\</:/g nomefile > nuovofile
[Invio]
Come faccio a ricavare da una pagina html tutti gli indirizzi e-mail in essa contenuti? Mi servirebbe per automatizzare un lavoro che adesso sto facendo a mano. Ho fatto qualche prova con il grep ma senza molti risultati.
---------
Se hai installato l'interprete perl, puoi risolvere con una riga di comando di questo tipo che ti garantisce una certa precisione:
$
cat file.html | perl -e 'while ($l=<STDIN>) {$l=~/mailto:\s*([\w-_\.]+\@[\w-_\.]+\.[\w-_\.]+)/ && print "$1\n";}'
[Invio]
Se gli indirizzi e-mail da estrapolare non compaiono sotto forma di tag HTML, puoi togliere la stringa relativa al mailto e lo spazio nella regexp.
Quale potrebbe essere lo script che prende tutti i file di una directory e li rinomina progressivamente (1.zip 2.zip ecc.) ?
---------
#!/usr/bin/perl $my_dir = @ARGV[0] || die "Non è stata specificata la directory\n"; @files = `ls $my_dir`; chop @files; foreach $f(@files) { $count++; $f =~ /\.(.*)/; rename("$my_dir/$f", "$my_dir/$count.$1"); }
oppure:
#!/bin/bash # _N=1 for _F in 'ls' do mv $_F ${_N}.zip _N='expr $_N + 1' done
se invece vuoi aggiungere solamente il suffisso .zip allora:
#!/bin/bash # for _F in 'ls' do mv $_F ${_F}.zip done
Come si fa in modo semplice quello che in Dos si faceva per esempio con:
ren abc*.txt abc*.asc ?
---------
Si può fare così:
$
for i in abc*.txt; do mv $i ${i%.txt}.asc; done
[Invio]
Se i file sono tantissimi ed eccedi la lunghezza massima di una riga di comando, puoi sempre fare:
$
find . -name "abc*.txt" | while read i; do mv $i ${i%.txt}; done
[Invio]
ma attenzione che find è ricorsivo.
Le forme:
${nomevariabile%%pattern}
${nomevariabile%pattern}
${nomevariabile##pattern}
${nomevariabile#pattern}
vengono espanse dalla shell nel contenuto della variabile tranne la parte all'inizio (`#') o alla fine (`%') che soddisfa il pattern. Il pattern è al solito un pattern di shell (*,?,[a-z]), e non un'espressione regolare.
Con `##' e `#' il pattern viene eventualmente tolto dall'inizio, mentre con `%%' e `%' viene eventualmente tolto dalla fine. La differenza tra `##' e `#' (o `%%' e `%') sta nel fatto che il primo rimuove il pattern più lungo possibile, mentre il secondo rimuove il più corto possibile.
Come si fa ad aggiungere una stessa parola alla fine di ogni riga di testo?
---------
$
cat file-name | sed "s/$/xxx/"
[Invio]
dove xxx è la stringa da aggiungere.
creare 2000 directory;
inserire in ognuna di esse un file .zip;
entrare nelle directory una ad una e lanciare unzip nomefile di volta in volta.
---------
La shell è lì apposta per questo genere di lavori basta dirgli cosa fare più o meno nei termini in cui l'hai descritto a parole, ossia:
#!/bin/sh cd /zipdir for f in * do mkdir /destinazione/$f unzip $f -d /destinazione/$f done
Lo script assume che tutti gli zip siano in /zipdir
e che la directory /destinazione
esista già.
Per il resto non fa altro che elaborare i file uno per uno, creare una directory con lo stesso nome del file .zip, e decomprimercelo dentro.
LDR --- Copyright © 1999-2000 Gaetano Paolone -- bigpaul @ pluto.linux.it