"Trova" l'output relativo alla directory


34

Vorrei utilizzare findper elencare tutti i file e le directory in modo ricorsivo in una determinata radice per cpioun'operazione. Tuttavia, non voglio che la directory principale stessa appaia nei percorsi. Ad esempio, attualmente ottengo:

$ find diskimg
diskimg
diskimg/file1
diskimg/dir1
diskimg/dir1/file2

Ma mi piacerebbe farlo

file1
dir1
dir1/file2

(nota che anche il root non è nel mio output desiderato, ma è facile liberarsene tail).

Sono su OS X e preferirei non installare altri strumenti (ad esempio GNU find) se possibile, poiché vorrei condividere lo script che sto scrivendo con altri utenti di OS X.

Sono consapevole che questo può essere fatto cutper tagliare l'elenco di root, ma sembra una soluzione non ottimale. C'è una soluzione migliore disponibile?


find diskimg/* | cut -d '/' -f2-
nik.shornikov,

Risposte:


18

Se quello che stai cercando di fare non è troppo complesso, potresti farlo con sed:

find diskimg | sed -n 's|^diskimg/||p'

Oppure cut:

find diskimg | cut -sd / -f 2-

puoi scegliere (quasi) qualsiasi separatore per il comando, quindi: find diskimg | grep -v '^diskimg$' | sed -e 's|^diskimg/||'(nota ho aggiunto anche '-e', e una ^buona pratica (non necessaria qui, dato che sei sicuro che ogni riga avrà questo ... ma comunque buona pratica , e salva un po 'di CPU;))
Olivier Dulac il

un altro modo senza grep: find diskimg | sed -e 's|^diskimg/*||' (il '/ *' corrisponderà a qualsiasi numero di '/', anche 0)
Olivier Dulac il

Questo cutcomando è più pulito di quello che ho usato; Mi piace. (Anche la sedsoluzione è buona, ma la ripetizione di diskimg/è un po 'sfortunata).
nneonneo,

29

cd nella directory prima:

cd diskimg && find . 

Al termine, tornerai nella directory principale.

I tuoi file saranno anteposti con ./ in questo caso; l'unico modo che vedo in giro sarebbe usare cut:

{ cd diskimg && find .; } | tail -n +2 | cut -c 3-

Utilizzare una subshell per evitare di modificare la directory corrente della shell (ciò non è necessario se si esegue il piping dell'output poiché il lato sinistro di una pipe è già in esecuzione in una subshell).

(cd diskimg && find .)

5
di essere di nuovo nella directory originale al termine: aggiungere parentesi: (cd diskimg && find . ; ). In questo modo cd diskimg && find .viene fatto in una subshell: quando quella subshell esce, si ritorna alla propria shell, in qualunque directory ci si trovasse.
Olivier Dulac il

1
find *è un altro modo per aggirare l'inutile prefisso
nik.shornikov il

23

Un altro, più complesso ma utilizzando solo l'approccio find dall'altra mia risposta:

find diskimg -mindepth 1 -printf '%P\n'

Non tutte le versioni di findsupporto printf.
Giordania,

1
Certamente; Il mio OSX no, a quanto pare. In parte perché ho offerto un'altra soluzione.
Stephan,

2
@Stephan: la prossima volta puoi combinare questi tipi di risposte in una sola. Non è necessario fornire risposte multiple per variazioni come questa.
slm

2
findSupporta solo GNU -printf, mentre molti BSD findhanno copiato alcune delle funzionalità di GNU find, nessuno ne ha -printfancora copiato (AFAIK).
Stéphane Chazelas,

il %Pper il relativo percorso era quello di cui avevo bisogno.
Fl0v0

4

Usa l' realpathutilità:

find diskimg -exec realpath --relative-to diskimg {} \;

Bene - grazie per avermelo mostrato --relative-to.
nneonneo,
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.