Comandi di piping dopo un xargs con pipe


38

HP-UX ***** B.11.23 U ia64 **** licenza per utente illimitato

find . -type d -name *log* | xargs ls -la

mi dà i nomi delle directory (quelli che contengono lognel nome della directory) seguiti da tutti i file all'interno di quella directory.

Le directory  /var/opt/SID/application_a/log/,  /var/opt/SID/application_b/log/,  /var/opt/SID/application_c/log/e così via contengono file di log.

Voglio solo gli ultimi due file di registro che siano elencati dal lscomando, che di solito trovo usando ls -latr | tail -2.

L'output deve essere qualcosa del genere ..

/var/opt/SID/application_a/log/
-rw-rw-rw-   1 user1    user1      59698 Jun 11  2013 log1
-rw-rw-rw-   1 user1    user1      59698 Jun 10  2013 log2
/var/opt/SID/application_b/log/
-rw-rw-rw-   1 user1    user1      59698 Jun 11  2013 log1
-rw-rw-rw-   1 user1    user1      59698 Jun 10  2013 log2
/var/opt/SID/application_c/log/
-rw-rw-rw-   1 user1    user1      59698 Jun 11  2013 log1
-rw-rw-rw-   1 user1    user1      59698 Jun 10  2013 log2

find . -type d -name *log* | xargs ls -la | tail -2non mi dà il risultato sopra. Quello che ottengo è un elenco degli ultimi due file di find . -type d -name *log* | xargs ls -lacomando.

Quindi posso eseguire il pipe dei comandi dopo un pipe xargs? In quale altro modo posso eseguire una query per ottenere l'elenco risultante dei file nel formato sopra?

find . -type d -name *log* | xargs sh -c "ls -ltr | tail -10"

mi dà un elenco di dieci nomi di directory all'interno della directory corrente che sembra essere /var/opt/SIDe che non è anche quello che voglio.


2
Dovresti citare *log*altrimenti la shell lo espanderà.
Anthon,

Ricorda che si sh -caspetta il nome del comando (parametro 0) come secondo argomento, quindi dovresti sempre farlo find . -type d -name *log* | xargs sh -c "ls -ltr | tail -10" lstail(nota lstailalla fine, che servirà come $0per la shell creata). Altrimenti il ​​primo dei tuoi risultati ricoprirà quel ruolo e rimarrà inutilizzato.
Jonas,

Risposte:


58

Ci sei quasi. Nel tuo ultimo comando, puoi usare -Iper fare lscorrettamente

-I replace-str

    Sostituisci le occorrenze di replace-str negli argomenti iniziali con nomi letti dall'input standard. Inoltre, gli spazi vuoti non quotati non terminano gli elementi di input; invece il separatore è il carattere di nuova riga. Implica -xe -L 1.

Quindi, con

find . -type d -name "*log*" | xargs -I {} sh -c "echo {}; ls -la {} | tail -2"

farai echola dir trovata da find, quindi esegui ls | tailsu di essa.


trova . -type d -name " log " | xargs -I {} sh -c "echo {}; ls -ltr {} | grep -E \" file_in | file_out \ "| tail -5" Ho usato questo.
anotherperson1

3
Faccio conxargs -n 1 sh -c 'echo $0'
Ginhing il

1
su macOS la sostituzione non ha funzionato con il comando citato, quindi è echo $0stata utile (e più comprensibile)
mpuncel

1
Per farlo funzionare con nomi di file con spazi, l'uso -print0, xargs -0e la fuga {}in virgolette doppie all'interno del shcomando:find . -type d -name "*log*" -print0 | xargs -0 -I {} sh -c "echo \"{}\";ls -la \"{}\" | tail -2"
Benedikt Köppel

Uso "xargs -n 1 sh -c" echo \ $ 0 | $ func "` se devo usare la variabile $ func
god


2

Solo in aggiunta a fredtantini e come chiarimento generale (dato che i documenti sono un po 'confusi):

Il xargs -I {}prenderà il {} caratteri dallo standard input e sostituirli con ciò che viene in dal tubo. Ciò significa che potresti effettivamente sostituirlo {}con qualsiasi combinazione di caratteri (forse per meglio adattarti al tuo gusto di programmazione preferito). Per esempio : xargs -I % sh -c "echo %". Se lo usi sempre xargs -I {}puoi sostituirlo con xargs -icome è la scorciatoia.

Il sh -cvi dirà il vostro bash / Shell per leggere il comando successivo da una stringa e non dallo standard input. Quindi scrivere sh -c "echo something"equivale a echo something.

Il xargs -I {} sh -c "echo {}"leggerà l'input è stato creato con sh -cil quale è echo {}. Dal momento che gli hai detto di sostituire {}con gli argomenti che hai preso dalla pipa, è quello che succederà.

Puoi facilmente testarlo anche senza tubazioni, basta digitare il comando sopra in un terminale. Qualunque cosa tu scriva dopo verrà inviata al terminale (Ctrl-D per uscire).

Nel ls -la {}comando succede di nuovo la stessa cosa. La {}viene sostituito con il contenuto del comando pre-tubo.

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.