[inizio] [indice generale] [precedente] [successivo] [indice analitico] [contributi]


345. Script per la shell

345.1 Script shell apparentemente inefficaci

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

o

$ . nomescript

in questo caso infatti sarà la shell corrente ad eseguire i comandi e
non un processo figlio.

D: aur
R: Ezio de Mauro, Andrea Manzini

345.2 Contare i caratteri

Esiste un comando o un sistema per contare i caratteri presenti in un file di testo?

#> cat nomefile | wc -l
conta le linee;

#> cat nomefile | wc -c
conta i caratteri;

#> man wc
per dettagli.

D: Andrea Nicosia
R: Riccardo Corsanici, Gianluca

345.3 Scelta di un file a caso in una directory

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

Possiamo sopperire alla mancanza di 'random' con l'equivalente
in perl:

perl -e '@files=`ls -1`;print "@files[int(rand($#files))]\n";'

D: Davide B.
R: Elisa Manara

345.4 Ricerca doppioni di file

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

dove per percorso_dir1 si intende il percorso completo della prima directory
da confrontare, e per percorso_dir2 il percorso della seconda, analogamente.

D: Mauro Barbieri
R: Roberto Previdi, Elisa Manara

345.5 Convertire in minuscolo tutti i file di una directory

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))}'

o con la shell:

for FILE in `/bin/ls`; do FILELOWER=`echo $FILE | tr A-Z a-z`; mv -i $FILE $FILELOWER; done 


D: Alkaid
R: Elisa Manara

345.6 Ordinare le righe di un file di testo al contrario

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

oppure:

cat nome_file | perl -e '@a=<STDIN>; while(@a){print pop(@a)};' > nuovo_file


Non basta il semplice:

cat nome_file | sort -r > nome_file.rev

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.

D: Ciro
R: Elisa Manara

345.7 Cerca, trova e copia

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 \;


D: Kernelz
R: Paolo Marchiori, Antirez, Alfonso De Gregorio, Nicola Bonelli, Stefano Brandimarte

345.8 Cambiare le estensioni dei file

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.

D: Alkaid
R: Elisa Manara

345.9 Sostituire caratteri in un file di testo

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

D: Andrea Nicosia
R: Elisa Manara

345.10 Rinominazione progressiva file - pt. 1

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
-----------------


D: Javakids
R: Elisa Manara, Riccardo Corsanici

345.11 Rinominazione progressiva file - pt. 2

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

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

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 una
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.

D: Marco Ciampa
R: Matteo Ianeselli, Roberto A. Foglietta

345.12 Aggiungere una stringa alla fine di ogni riga di un file testo

Come si fa ad aggiungere una stessa parola alla fine di ogni riga di testo?

cat file-name | sed "s/$/xxx/"

dove xxx è la stringa da aggiungere.


D: Andrea Nicosia
R: Franco Canovi

345.13 Decomprimere diversi file in directory sequenziali

Ho le seguenti necessità:

  1. creare 2000 directory;

  2. inserire in ognuna di esse un file .zip;

  3. 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;
- 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.

D: Antonio Bronzini
R: Luciano Di Lucrezia

---------------------------

LDR --- Copyright © 1999-2000 Gaetano Paolone --  bigpaul @ pluto.linux.it


[inizio] [indice generale] [precedente] [successivo] [indice analitico] [contributi]