Script della shell di Linux per ogni file in una directory Prendi il nome del file ed esegui un programma


85

Scenario :

Una cartella nel sistema Linux. Voglio scorrere ogni file .xls in una cartella.

Questa cartella è costituita tipicamente da varie cartelle, vari tipi di file (.sh, .pl, .csv, ...).

Tutto quello che voglio fare è scorrere tutti i file nella root ed eseguire un programma solo sui file .xls.

Modificare :

Il problema è che il programma che devo eseguire è "xls2csv" per convertire dal formato .xls al formato .csv. Quindi, per ogni file .xls devo prendere il nome del file e aggiungerlo a .csv.

Ad esempio, ho un file test.xls e gli argomenti per xls2csv sono: xls2csv test.xls test.csv

Avevo senso?

Risposte:


200

bash:

for f in *.xls ; do xls2csv "$f" "${f%.xls}.csv" ; done

Semplicemente fantastico! Funziona perfettamente! Grazie mille!
ThinkCode

6
Questo è esattamente quello che stavo cercando per un motivo completamente diverso. Un po 'di editing ed è perfetto per le mie esigenze specifiche. Grazie = D E per chiunque non sia chiaro su cosa fa: $ {f% .ext} sostituisce il nome del file senza l'estensione, quindi in questo esempio, verrà visualizzato "nomefile.csv" anziché "nomefile. xls.csv ".
Frungi

Heh Ho cercato su Google "linux foreach txt file" e ho trovato questo. Questo era esattamente ciò di cui avevo bisogno, stavo effettivamente cercando di usare xls2csv ma ​​ho pensato che non avrei trovato alcun risultato cercando quello :)
akiller

1
$ f avrà un valore di * .xls se * .xls non corrisponde a nessun file. Controlla la mia risposta se questo è un problema.
Andrew Bourgeois

Oppure puoi semplicemente impostare nullglobper saltare il ciclo.
Ignacio Vazquez-Abrams

15
for i in *.xls ; do 
  [[ -f "$i" ]] || continue
  xls2csv "$i" "${i%.xls}.csv"
done

La prima riga nel docontrolla se il file "corrispondente" esiste davvero, perché nel caso in cui nulla corrisponda al tuo for, doverrà eseguito con "* .xls" come $i. Questo potrebbe essere orribile per il tuo xls2csv.


13

Guarda il ritrovamento comando .

Quello che stai cercando è qualcosa di simile

find . -name "*.xls" -type f -exec program 

Modifica post

find . -name "*.xls" -type f -exec xls2csv '{}' '{}'.csv;

verrà eseguito xls2csv file.xls file.xls.csv

Più vicino a quello che vuoi.


find -maxdepth 1per escludere le sottocartelle. Questo converte anche test.xlsin test.xls.csvinvece di test.csv. Quindi non esattamente quello che chiedeva OP, ma abbastanza vicino.
effimero

L'uso {}come sottostringa di un argomento piuttosto che un intero argomento è un'estensione GNU, non garantita dalle specifiche POSIX per find. In quanto tale, questa risposta non è necessariamente portabile su piattaforme non GNU.
Charles Duffy

4
find . -type f -name "*.xls" -printf "xls2csv %p %p.csv\n" | bash

bash 4 (ricorsivo)

shopt -s globstar
for xls in /path/**/*.xls
do
  xls2csv "$xls" "${xls%.xls}.csv"
done

Ottima soluzione. L'ho usato per permettermi di scrivere haml / scss e compilare in html / css in fase di progettazione per un progetto node.js.
Chris Kemp

1
Questo è assolutamente pericoloso se non ti fidi che i nomi dei tuoi file non contengano cose come $(rm -rf /)... o solo spazi.
Charles Duffy
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.