Ordina l'output di find -exec ls


14

È possibile l'output di find … -exec ls -ls ;ordinati in ordine alfabetico, per nome file?

Questo è il mio comando cron:

find /home/setefgge/public_html -type f -ctime -1 -exec ls -ls {} \;

Questo comando funziona bene, per la maggior parte. Ma i risultati non sono ordinati in nessuna sequenza significativa. Sarebbe molto utile se fossero ordinati in base al campo del nome del file.


1
Usi zsh? ls -ls **/*(.)
Kevin,

@Kevin Non proprio - lsordinerebbe.
Gilles 'SO- smetti di essere malvagio' il

Risposte:


14

Presumo che i nomi dei tuoi file non contengano nuove righe.

find /home/setefgge/public_html -type f -ctime -1 -exec ls -nls {} + | sort -k 10

Usare +invece di ;terminare l' -execazione rende più veloce raggruppando le invocazioni di ls. È possibile ordinare eseguendo il piping tramite il sortcomando; digli di iniziare l'ordinamento dal decimo campo (i primi 9 sono i metadati: blocchi, permessi, conteggio dei collegamenti, utente, gruppo, dimensioni e 3 campi data / ora). L'opzione -nindica lsdi utilizzare valori numerici per l'utente e il gruppo, evitando così il rischio di nomi di utenti o gruppi contenenti spazi bianchi.

In alternativa, con zsh, puoi cavartela senza supporre alcun nome usando i qualificatori glob per raccogliere e ordinare i file ed zargseseguirli lspiù volte se la riga di comando fosse troppo lunga. Hai bisogno di GNU ls(in particolare la sua -fopzione) per evitare di riordinare ls(un altro approccio sarebbe emulare lscon zsh zstat).

autoload -U zargs
zargs -- /home/setefgge/public_html/**/*(.c-2) -- ls -lnsf

Grazie mille! Usando il primo comando che hai inviato fa l'ordinamento. Il numero sarebbe ancora 10 se utilizzo un percorso più breve? Ad esempio, se eseguo lo stesso comando da / home / setefgge invece che da public_html?
MaJ

@MaJ 10 è il numero di campi ignorati, non ha nulla a che fare con la dimensione del nome del file.
Gilles 'SO- smetti di essere malvagio' il

Grazie. Apprezzo il tuo aiuto e anche l'aiuto fornito da tutti gli altri. Considero risolto questo problema. Il mio comando cron ora sta ordinando i file. Questa è la prima volta che invio una domanda a Stackexchange. Non vedo un'opzione "Risolto". Se qualcuno di voi sa come pubblicare questo come risolto, si prega di andare avanti e farlo. Grazie!
MaJ

@MaJ La cosa più vicina a cui dobbiamo porre una domanda come risolta è contrassegnare una delle risposte accettate. Solo tu, il richiedente, puoi farlo. Per fare ciò, fai clic sul segno di spunta accanto alla risposta che ti ha aiutato di più. Se accetti una risposta, otterrai altri 2 punti reputazione e successivamente potrai votare i post; puoi votare tutti i post che hai trovato utili. Per ulteriori informazioni, consultare la pagina del tour e la pagina della guida su cosa fare quando qualcuno risponde alla tua domanda .
Gilles 'SO- smetti di essere malvagio' il

1

Perché non convogliare il risultato di find through sort e quindi eseguire ls per ciascuna delle righe?

find . -type f -ctime -1 | sort | while IFS= read -r filename; do ls -ls "$filename"; done

1

POSIX ha questo da dire sulle date in un ls -lelenco ong:

Il <date and time>campo deve contenere la data e il timestamp appropriati dell'ultima modifica del file. Nelle impostazioni internazionali POSIX, il campo deve essere equivalente all'output del comando date seguente:

date "+%b %e %H:%M"

... se il file è stato modificato negli ultimi sei mesi o:

date "+%b %e %Y"

Tenendo conto di ciò e assicurando che se ci sono nuove righe in un nome file sono adeguatamente disturbate dall'opzione POSIX specificata ls -q, è relativamente facile preparare una regex per un lsrisultato senza findaffatto:

d=$(date "+%b %e") y=$(date --date=yesterday "+%b %e")
echo "$d" "$y"

###OUTPUT###
Jul  5 Jul  4

grepper questo e restituirai solo le righe che contengono le stringhe che rappresentano le date di oggi o di ieri. Il seguente comando aggiunge un po 'a quello:

ls -alRcq | sed "1H;/^-/!{/./d;N;h};/$d\|$y/!d;x;/\n/p;g"

ls le opzioni sono costituite da:

  1. -a restituisce tutti i file in una directory, inclusi quelli che iniziano con a .dot
  2. -l lista lunga
  3. -R elenca ricorsivamente tutte le directory secondarie
  4. -c visualizzare il tempo di modifica anziché il tempo di accesso
  5. -qrestituisce la shell glob ?anziché caratteri non stampabili o \tab in un nome file

Tali risultati vengono passati sul |pipefile a sedcui corrisponde solo:

  1. La riga vuota che precede un nome percorso e la riga seguente
  2. Le righe che iniziano con - (in altre parole - non dper directory) che contengono anche il tuo date.
  3. Tuttavia, non stampa le righe del nome percorso, a meno che la directory che nominano non contenga effettivamente i file filtrati.

L'output è simile al seguente:

ls -alRcq --color=always | 
sed "1H;/^-/!{/./d;N;h};/$d\|$y/!d;x;/\n/p;g"

###OUTPUT###
.:
-rw------- 1 mikeserv mikeserv   2086 Jul  4 10:52 .bash_history
-rw------- 1 mikeserv mikeserv   2657 Jul  4 15:20 .lesshst
-rw-r--r-- 1 mikeserv mikeserv    681 Jul  5 05:18 .zdirs
-rw------- 1 mikeserv mikeserv 750583 Jul  5 08:28 .zsh_history
-rw-r--r-- 1 mikeserv mikeserv    166 Jul  4 23:02 Terminology.log
-rw-r--r-- 1 mikeserv mikeserv 433568 Jul  4 13:34 shot-2014-06-22_17-10-16.jpg
-rw-r--r-- 1 mikeserv mikeserv 445192 Jul  4 13:34 shot-2014-06-22_17-11-06.jpg

./.cache/efreet:
-rw------- 1 mikeserv mikeserv  37325 Jul  4 22:51 desktop_localhost_C.eet
-rw------- 1 mikeserv mikeserv  37325 Jul  4 23:30 desktop_localhost_en_US.eet
-rw------- 1 mikeserv mikeserv  24090 Jul  4 22:51 desktop_util_localhost_C.eet
-rw------- 1 mikeserv mikeserv  24090 Jul  4 23:30 desktop_util_localhost_en_US.eet
-rw------- 1 mikeserv mikeserv  16037 Jul  4 23:30 icon_themes_localhost.eet
-rw------- 1 mikeserv mikeserv   3117 Jul  4 23:30 icons___efreet_fallback_localhost.eet
-rw------- 1 mikeserv mikeserv 768039 Jul  4 23:30 icons_gnome_localhost.eet
-rw------- 1 mikeserv mikeserv  18589 Jul  4 23:30 icons_hicolor_localhost.eet

./.config:
-rw-r--r-- 1 mikeserv mikeserv   30 Jul  4 19:10 pavucontrol.ini

./.config/chrome:
-rw-r--r-- 1 mikeserv mikeserv 94332179 Jul  4 13:36 conf.tar.lz4.bak

Sì, funziona anche con LS_COLORS- che è probabilmente una priorità bassa per il tuo cronovviamente, ma hey le tue opzioni sono aperte.

In ogni caso, ciò offre alcuni vantaggi significativi rispetto ad altre possibili soluzioni.

  1. In primo luogo find+ lscoinvolge più invocazioni - questo implica solo un singolo lsprocesso, ed è per questo che è in grado di ordinare in modo affidabile tutto - cosa che fa di default - e quindi sortè anche reso accessorio.

  2. Qualsiasi soluzione che coinvolge finded sorte lspraticamente fa tutto il lavoro due volte. lse findrisolverà ogni percorso e statogni file. lse sortordinerà entrambi tutti i risultati. Probabilmente è meglio invece usare solo il singolo ls.

  3. Quindi ovviamente c'è la datee sedparti di questa risposta. La cosa importante da notare al riguardo è che fai la parte difficile e ottieni prima la regex - e solo una volta - e in seguito poti solo un singolo elenco di risultati piuttosto che dire, ottenere risultati, ottenere risultati, ordinare risultati e ordinare risultati.

  4. Ciò non si interrompe sui nomi di file contenenti newline, come probabilmente lo faranno altre soluzioni. Questa soluzione ha i suoi avvertimenti - che spiego in seguito - ma sono piccoli e facili da gestire. Secondo me, questa è la soluzione più solida qui.

Esistono due casi in cui il comando sopra potrebbe causare problemi. Il primo riguarda i ?globs nei nomi dei file - mentre com'è è già una soluzione più solida di qualsiasi altra offerta qui, e la probabilità che incontrerai un ?a è abbastanza piccola da sola, c'è una possibilità che risolverli potrebbe corrispondere a più di un nome file. Si prega di consultare questo per ulteriori informazioni su questo argomento.

L'altra possibilità comporta un falso positivo, ad esempio se hai un nome file che corrisponde effettivamente alla datestringa per la quale stiamo cercando grepma che non è stato effettivamente modificato in nessuno di quei giorni. Non sto contando sul fatto che si tratti di un problema, ma, se lo è, chiedilo e probabilmente posso aiutarti a rendere il regex più specifico al fine di gestirlo.


0

Puoi effettivamente usare una combinazione di find, xargs e ls.

Ecco un comando di esempio: find . -type f -print0 | xargs -0 ls -lt

  • find ricercherà ricorsivamente tutti i file nella directory corrente.
  • xargs passerà questo elenco di file al lscomando in una singola chiamata (a condizione che findrestituisca meno dei ARG_MAXfile).
  • ls -lt ordinerà questi file per ora e formatterà l'output

Per recuperare il tuo sistema ARG_MAXpuoi digitare:

$ getconf ARG_MAX
> 2621440

-1
ls -l $(find /home/setefgge/public_html -type f -ctime -1 | sort)

1
lsfa il proprio ordinamento, quindi il piping dell'output di findthrough sortè inutile. Inoltre il tuo comando modifica i nomi dei file contenenti spazi bianchi (tra gli altri) e fallirà se ci sono troppi nomi di file.
Gilles 'SO- smetti di essere malvagio'
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.