GNU/Linux >> Linux Esercitazione >  >> Linux

Verificare se ci sono file che corrispondono a un modello per eseguire uno script?

Sto cercando di scrivere un if istruzione per verificare se ci sono file che corrispondono a un determinato modello. Se c'è un file di testo in una directory, dovrebbe eseguire un determinato script.

Il mio codice attualmente:

if [ -f /*.txt ]; then ./script fi

Si prega di fornire alcune idee; Voglio eseguire lo script solo se è presente un .txt nella directory.

Risposta accettata:

[ -f /*.txt ]

ritornerebbe vero solo se ce n'è uno (e solo uno) file non nascosto in / il cui nome termina con .txt e se quel file è un file normale o un collegamento simbolico a un file normale.

Questo perché i caratteri jolly vengono espansi dalla shell prima di essere passati al comando (qui [ ).

Quindi, se c'è un /a.txt e /b.txt , [ verranno passati 5 argomenti:[ , -f , /a.txt , /b.txt e ] . [ si lamenterebbe quindi che -f riceve troppi argomenti.

Se vuoi controllare che il *.txt pattern si espande in almeno un file non nascosto (normale o meno), nel bash guscio:

shopt -s nullglob
set -- *.txt
if [ "$#" -gt 0 ]; then
  ./script "[email protected]" # call script with that list of files.
fi
# Or with bash arrays so you can keep the arguments:
files=( *.txt )
# apply C-style boolean on member count
(( ${#files[@]} )) && ./script "${files[@]}"

shopt -s nullglob è bash specifico (shopt è, nullglob in realtà viene da zsh ), ma shell come ksh93 , zsh , yash , tcsh avere dichiarazioni equivalenti.

Con zsh , il test per ci sono file che corrispondono a un modello può essere scritto utilizzando una funzione anonima e il N (per nullglob ) e Y1 (per fermarsi dopo la prima ricerca) qualificatore glob:

if ()(($#)) *.txt(NY1); then
  do-something
fi

Nota che quelli trovano quei file leggendo il contenuto della directory, non tenta affatto di accedere a quei file, il che lo rende più efficiente delle soluzioni che chiamano comandi come ls o stat su quell'elenco di file calcolato dalla shell.

Lo standard sh l'equivalente sarebbe:

set -- [*].txt *.txt
case "$1$2" in
  ('[*].txt*.txt') ;;
  (*) shift; script "[email protected]"
esac

Il problema è che con le shell Bourne o POSIX, se un pattern non corrisponde, si espande su se stesso. Quindi se *.txt si espande in *.txt , non sai se è perché non c'è .txt file nella directory o perché esiste un file chiamato *.txt . Utilizzando [*].txt *.txt permette di discriminare tra i due.

Ora, se vuoi controllare che il *.txt corrisponde ad almeno un normale file o collegamento simbolico a un file normale (come il tuo [ -f *.txt ] suggerisce di volerlo fare), o che tutti i file che corrispondono a *.txt sono normali file (dopo la risoluzione del collegamento simbolico), questa è un'altra questione.

Correlati:come generare uno script di creazione tabella senza chiave primaria ed esterna in Oracle?

Con zsh :

if ()(($#)) *.txt(NY1-.); then
  echo "there is at least one regular .txt file"
fi
if ()(($#)) *.txt(NY1^-.); then
  echo "there is at least one non-regular .txt files"
fi

(rimuovere il - se vuoi fare il test prima della risoluzione del collegamento simbolico, considera i collegamenti simbolici come file non regolari indipendentemente dal fatto che puntino a file normali o meno).


Linux
  1. Inserisci più righe di dati in un file dopo le corrispondenze dei modelli utilizzando lo script della shell di Linux

  2. Trova file duplicati?

  3. Come cercare in file specifici che corrispondono a un modello?

  4. Corrispondenza del modello di script Bash

  5. Esiste un programma/script per modificare i file .conf?

Esegui file binari in Linux

Trova ed elimina il file più vecchio se ci sono più di X file in una directory in Linux

Verifica che ci siano almeno due argomenti forniti in uno script bash

Perché i file .so sono eseguibili?

Come passare più argomenti da eseguire con lo script .sh

Come scoprire se ci sono file in una cartella ed uscire di conseguenza (in KSH)