как вывести список файлов без каталогов и отфильтровать по имени (параметры ls)

<p>у меня есть каталог с именем <code>uploads</code>. он содержит несколько файлов, а также несколько подкаталогов, которые в свою очередь содержат файлы.</p><p>есть ли способ, которым я могу (за один шаг) сделать следующее:</p><ol> <li> <p>перечислять только файлы в корневом каталоге загрузок - я не хочу видеть имена подпапок или их содержимое;</p> <p><strong>и</strong></p> </li> <li> <p>не перечисляйте файлы, начинающиеся с <code>t\_</code></p> </li> </ol><p>я знаю о <code>-d</code> флаг, но это не дает мне того, чего я хочу.</p>

<p>это звучит как работа для <code>find</code>.</p><ul> <li>используйте <code>-maxdepth</code> чтобы вернуть только текущий каталог, а не рекурсивно искать внутри подпапок</li> <li>используйте <code>-type f</code> чтобы возвращать только файлы, а не каталоги или узлы устройств или что-либо еще</li> <li>используйте комбинацию, если <code>-not</code> а также <code>-name</code> чтобы избежать файлов с именами, которые вам не нужны</li> </ul><p>это может сложиться так:</p><pre><code>find /path/to/uploads -maxdepth 1 -type f -not -name 't\_*' </code></pre>

<p>gnu ls (то есть команда ls в не встроенных системах linux и cygwin, также доступная в некоторых других устройствах) имеет возможность скрыть некоторые файлы на основе их имен. там нет способа игнорировать каталоги, хотя.</p><pre>\_<code>ls --hide='t\_*' uploads </code>\_</pre><p>другой подход заключается в том, чтобы заставить ваш shell выполнить сопоставление. bash, ksh и zsh имеют шаблон отрицания <code>!(t\_*)</code> для соответствия всем файлам, кроме тех, которые соответствуют \_<code>t*</code>\_; в bash эту функцию нужно включить с помощью \_<code>shopt -s extglob</code>\_, а в zsh ее нужно включить с помощью \_<code>setopt ksh\_glob</code>\_. zsh также имеет эквивалентный синтаксис \_<code>^t\_*</code>\_, который необходимо включить с помощью \_<code>setopt extended\_glob</code>\_. это все еще не игнорирует каталоги. в zsh есть дополнительная функция, которая позволяет сопоставлять файлы не только по имени, но и по метаданным и т. д .: <a href="http://zsh.sourceforge.net/doc/release/expansion.html#glob-qualifiers">glob qualifiers</a> . добавьте \_<code>(.)</code>\_ в конце совпадения, чтобы ограничиться обычными файлами. отрицание \_<code>^</code>\_ является частью синтаксиса соответствия имен, поэтому <code>^t\_*(.)</code> означает "все обычные файлы, не соответствующие \_<code>t\_*</code>\_", а не "все файлы, которые не являются обычными файлами, совпадающими с \_<code>t\_*</code>\_".</p><pre>\_<code>setopt extended\_glob # put this in your ~/.zshrc ls uploads/^t\_*(.) </code>\_</pre><p>если вы оказались без продвинутых инструментов, вы можете сделать это на любом unix с помощью <code>find</code>. это не та вещь, которую вы обычно печатаете в командной строке, но она мощная и точная. <a href="https://unix.stackexchange.com/questions/15950/how-to-list-files-without-directories-and-filter-by-name-ls-options/15951#15951">caleb уже показал, как это сделать с помощью gnu find</a> . опция \_<code>-maxdepth</code>\_ не переносима; вместо нее можно использовать \_<code>-prune</code>\_, переносимо остановить <code>find</code> от повторения.</p><pre>\_<code>find uploads/* -type d -prune -o \! -type f -name 't\_*' -print </code>\_</pre><p>замените \_<code>-print</code>\_ на \_<code>-exec ls -lg -- {} +</code>\_, чтобы выполнить <code>ls</code> с вашими любимыми параметрами для файлов.</p><p>все команды выше скрывают точечные файлы (то есть файлы, чье имя начинается с \_<code>.</code>\_). если вы хотите отобразить их, передайте \_<code>-a</code>\_ в <code>ls</code> или добавьте спецификатор глобуса <code>d</code> в zsh (<code>ls uploads/^t\_*(.d)</code>). с <code>find</code> вы можете использовать другой подход, чтобы заставить его повторять только один уровень (<code>find</code> не обрабатывает точечные файлы специально). это полностью работает, только если вы запускаете <code>find</code> в текущем каталоге.</p><pre>\_<code>cd uploads && find . -name . -o -type d -prune -o \! -type f -name 't\_*' -print </code>\_</pre>

<pre><code>ls -l /folder | grep ^- | awk '{print $9}' 

ls -l | grep -v ^d | grep name$ </code></pre>

<p>если проблема переносимости find -maxdepth является проблемой, вы можете использовать:</p><pre><code>ls -l uploads/ | awk '/^-/ && $9 !~/^t_/ {print $9}' </code></pre><p>я не эксперт, но я думаю, что это должно работать. я полагаю, это выглядит немного загадочно, но если вы говорите на awk, это действительно не так. $ nf можно использовать вместо $ 9. вы также можете сделать:</p><pre><code>ls -l uploads/ | awk '/^-/' | awk '!/^t\_/ {print $9}' который делает то же самое (но, возможно, менее эффективно, чем первый ???).на самом деле, подумав о других постах, выглядитls -l --hide=t_ uploads/ | awk '/^-/ {print $9}' </code></pre><p>это еще короче и яснее.</p><p>кто-нибудь, пожалуйста, поправьте меня, если я ошибаюсь. :-)</p>

<p>я нашел эти короткие пути:</p><pre><code>ls -p uploads | grep -ev '/' </code></pre><p>или</p><pre><code>ls -pit\_* uploads | grep -v / </code></pre>

<p>позвольте мне сделать это, используя <code>ls</code> и трубы:</p><pre><code>ls -l --hide='t\_*' uploads/ | grep -v ^d | tr -s ' ' | cut -d ' ' -f 9 </code></pre><p>скажем, последний столбец 9-й.</p>