Перераховуйте файли рекурсивно в Linux CLI з контуром відносно поточного каталогу


224

Це схоже на це питання , але я хочу включити шлях до поточного каталогу в unix. Якщо я виконую наступне:

ls -LR | grep .txt

Він не включає повний шлях. Наприклад, у мене є така структура каталогів:

test1/file.txt
test2/file1.txt
test2/file2.txt

Верхній код поверне:

file.txt
file1.txt
file2.txt

Як я можу змусити його включати шляхи відносно поточного каталогу за допомогою стандартних команд Unix?


4
Це просто показує, що ls відсутня у цій функції.
Арджун Сінгрі

1
Прикро, що всі ці рішення вимагають findабо tree. Я перекладаю на андроїд пристрій, де я, мабуть, є лише один ls, і жоден із цих інших інструментів: /
Ponkadoodle

Відповіді:


304

Використовуйте пошук:

find . -name \*.txt -print

У системах, які використовують GNU, як і більшість дистрибутивів GNU / Linux, ви можете залишити -print.


11
... і з цього питання ви можете залишити "."
Адам Міц

7
Для абсолютних шляхів використовуйтеfind $(pwd) -name \*.txt
Zags

2
Якщо шаблон має частину імені каталогу, слід використовувати -path "*docs/*.txt"замість -name. -wholenameте саме, що-path
тире

9
Використовувати -type fлише для повернення файлів, а не каталогів, символічних посилань тощо
користувач

2
-name "*.txt"буде НЕ відповідати file.TXT- завжди використовувати -iname "*.txt"замість який нечутливий до регістру.
ccpizza

73

Використовуйте за treeдопомогою -f(повний шлях) та -i(без відступів рядків):

tree -if --noreport .
tree -if --noreport directory/

Потім ви можете grepвідфільтрувати потрібні.


Якщо команда не знайдена, ви можете встановити її:

Введіть наступну команду, щоб встановити команду дерева на RHEL / CentOS та Fedora linux:

# yum install tree -y

Якщо ви використовуєте Debian / Ubuntu, Mint Linux введіть у свій термінал наступну команду:

$ sudo apt-get install tree -y

2
будь-яке налаштування, щоб перелічити лише файли та виключити папки?
thebugfinder

25

Спробуйте find. Ви можете шукати його точно на сторінці "man", але це так:

find [start directory] -name [what to find]

так для вашого прикладу

find . -name "*.txt"

повинен дати вам те, що ви хочете.



5

Це робить трюк:

ls -R1 $PWD | while read l; do case $l in *:) d=${l%:};; "") d=;; *) echo "$d/$l";; esac; done | grep -i ".txt"

Але це робиться через "гріх" з розбором ls, хоча громади GNU та Ghostscript вважають поганою формою.


2
@CAFEBABE: вважається табу для аналізу результатів, lsоскільки це, як правило, призводить до помилок. Пропозиція, про яку йдеться, намагалася це викрити. У ньому також був жарт, який я зняв.
Адам Кац

4
DIR=your_path
find $DIR | sed 's:""$DIR""::'

'sed' видалить 'your_path' з усіх результатів 'find'. І ви отримуєте відносно шляху "DIR".


це саме те, що мені потрібно, але воно все ще виплющує повний шлях для мене?
v3nt

1
не використовуйте апострофа - find / tmp | sed s: "/ tmp" :: | детальніше
Kieren Dixon

4

Щоб отримати фактичні повні назви файлів шляху потрібних файлів за допомогою команди find, використовуйте його за допомогою команди pwd:

find $(pwd) -name \*.txt -print

1

Ось сценарій Perl:

sub format_lines($)
{
    my $refonlines = shift;
    my @lines = @{$refonlines};
    my $tmppath = "-";

    foreach (@lines)
    {
        next if ($_ =~ /^\s+/);
        if ($_ =~ /(^\w+(\/\w*)*):/)
        {
            $tmppath = $1 if defined $1;    
            next;
        }
        print "$tmppath/$_";
    }
}

sub main()
{
        my @lines = ();

    while (<>) 
    {
        push (@lines, $_);
    }
    format_lines(\@lines);
}

main();

використання:

ls -LR | perl format_ls-LR.pl

Це жахлива програма Perl. Це, мабуть, у 2-3 рази довше і складніше, ніж потрібно.
Бред Гілберт

1

Ви можете створити функцію оболонки, наприклад, у своєму .zshrcабо .bashrc:

filepath() {
    echo $PWD/$1
}

filepath2() {
    for i in $@; do
        echo $PWD/$i
    done
}

Перший працював би лише на одних файлах, очевидно.


1

Знайдіть файл у файловій системі під назвою "ім'я файлу", починаючи пошук з кореневого каталогу "/". Ім'я файлу

find / -name "filename" 

1

Якщо ви хочете зберегти деталі, що надходять з таким розміром файлу тощо, як це, то це має спрацювати.

sed "s|<OLDPATH>|<NEWPATH>|g" input_file > output_file

1

У рибній оболонці ви можете це зробити, щоб рекурсивно перелічити всі pdfs, включаючи ті, що в поточному каталозі:

$ ls **pdf

Просто видаліть "pdf", якщо ви хочете, щоб файли будь-якого типу.


0

Ви можете реалізувати таку функціональність, як ця.
По-перше, використовуючи команду ls, вказану на цільовий каталог. Пізніше за допомогою команди find фільтруйте результат з неї. З вашого випадку це звучить так - завжди ім'я файлу починається зі слова file***.txt

ls /some/path/here | find . -name 'file*.txt'   (* represents some wild card search)

0

У моєму випадку з командою дерева

Відносний шлях

tree -ifF ./dir | grep -v '^./dir$' | grep -v '.*/$' | grep '\./.*' | while read file; do
  echo $file
done

Абсолютний шлях

tree -ifF ./dir | grep -v '^./dir$' | grep -v '.*/$' | grep '\./.*' | while read file; do
  echo $file | sed -e "s|^.|$PWD|g"
done
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.