Jak usunąć początkowe „./” w uniksowym „find”?

140
find . -type f -print

drukuje

./file1
./file2
./file3

Każdy sposób na wydrukowanie

file1
file2
file3

?

chlebjesus
źródło
1
jeśli użyłeś -exec /path/to/myscript.sh {} w swoim find, -printf '%P\n'nie działa. Zamiast tego muszę zrobić ./prefiks w skrypcie przez:p=${1#"./"}
trueadjustr
Jeśli robisz to tylko dla jednego pliku:f=`find . -name migration`; echo ${f/.\//}
masterxilo

Odpowiedzi:

38

Jeśli znajdują się tylko w bieżącym katalogu

find * -type f -print

Czy tego chcesz?

Tim Green
źródło
21
Spowoduje to pominięcie plików z nazwami zaczynającymi się od kropki.
Sean,
2
Źle, w zależności od ustawień powłoki * może nie dać "ukrytych" plików / katalogów - tych, które zaczynają się od kropki (.) Spróbuj uruchomić to polecenie w swoim katalogu domowym, a następnie po prostu "znajdź -type f" i zobacz różnicę .
Ilia K.
35
Bardziej istotnym problemem jest to, że powłoka ocenia znak „*”. W rzeczywistości masz typ sytuacji wstrzyknięcia złośliwego kodu. Utworzenie pliku o nazwie „--exec rm” i innego o nazwie „zzzz;” byłoby trywialne. Żegnajcie pliki.
CWF
6
To jest niebezpieczne. Jeśli nazwa pliku zaczyna się od myślnika, będzie traktowana jako opcja do znalezienia i może się nie powieść lub może potencjalnie spowodować uszkodzenie.
Dale Anderson
4
Dlaczego jest to -printwymagane? Dało ten sam wynik bez tej flagi.
user13107
239

Znajdź tylko zwykłe pliki w bieżącym katalogu i wydrukuj je bez ./przedrostka „ ”:

find -type f -printf '%P\n'

Od znalezienia człowieka, opis -printfformatu:

% P Nazwa pliku z nazwą argumentu wiersza poleceń, pod którym została znaleziona, została usunięta.

Ilia K.
źródło
18
+1 Dobre rozwiązanie, jeśli Twoja wersja findobsługuje -printf(nie wszystkie).
Todd Owen,
2
Jak powiedział Todd, ale dokładniej: to nie jest POSIX 7.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
8
Obsługiwana lub nie, jest zdecydowanie bezpieczniejsza niż zaakceptowana odpowiedź.
Dale Anderson
10
Możesz użyć \0zamiast, \njeśli chcesz to xargs -0find -type f -printf '%P\0' | xargs -0 head
potokować
1
@Quanlong, to działa na macOS, jeśli ty brew install findutils;)
blockloop
58

Użyj sed

find . | sed "s|^\./||"
Lie Ryan
źródło
2
To jest moje ulubione rozwiązanie; jest zgodny z POSIX (działa praktycznie wszędzie, nawet w systemach wbudowanych), jest bardzo krótki i jest mało prawdopodobne, aby powodował nieoczekiwane zachowanie. To powinna być akceptowana odpowiedź.
Jody Bruchon
6
Jak można to połączyć find -exec?
Paul Wintz,
find -exec sh -c "echo {} | sed 's|^\./||'" \; lub find -exec sh -c "sed 's|^\./||' <<< '{}'" \;
xenithorb
12

może być krótszy

find * -type f
ghostdog74
źródło
Lepiej 2> /dev/nullzignorować błąd zgłaszany, gdy polecenie jest uruchamiane w pustym katalogu.
neevek
2

Innym sposobem na usunięcie ./jest użycie cut:

find -type f | cut -c3-

Więcej wyjaśnień można znaleźć tutaj

banjoAtix
źródło
2

Inny sposób na usunięcie ./

find * -type d -maxdepth 0
Valheru
źródło
Chociaż ten kod może rozwiązać problem, w tym wyjaśnienie, jak i dlaczego to rozwiązuje problem, naprawdę pomogłoby poprawić jakość twojego posta i prawdopodobnie zaowocowałoby większą liczbą pozytywnych głosów. Pamiętaj, że odpowiadasz na pytanie do czytelników w przyszłości, a nie tylko osoba, która zapyta teraz. Zmień swoją odpowiedź, aby dodać wyjaśnienia i wskazać, jakie ograniczenia i założenia mają zastosowanie.
David Buck
2

Ponieważ -printfopcja nie jest dostępna na OSX, findtutaj jest jedno polecenie, które działa na OSX find, na wypadek, gdyby ktoś nie chciał zainstalować gnu findza pomocą brewitp:

find . -type f -execdir printf '%s\n' {} + 
anubhava
źródło
1
Niestety powoduje to usunięcie całej ścieżki każdego znalezionego pliku, w tym podkatalogów pośrednich, i po prostu wypisuje samą nazwę pliku.
PLL
1
Masz rację. To rozwiązanie jest dobre tylko dla plików w bieżącym katalogu. W przypadku plików zagnieżdżonych musimy użyć:find . -type f -exec bash -c 'for f; do echo "${f#./}"; done' {} +
anubhava