Intereting Posts
Что происходит, когда ваш пароль истекает, и вы используете проверку подлинности ключа? Просмотреть удаленное значение $ PATH внутри сценария оболочки Как восстановить файлы с одного поврежденного диска mdadm raid1? «Недостаточно, чтобы запустить массив» gpg-agent запрашивает парольную фразу, но закрытый ключ ssh не имеет Скопировать дату создания файла в метаданные в ffmpeg почему php не может видеть / tmp-файлы Контейнер Docker подключает iptables к прокси Как удалить <? Xml в * начале строки * с sed? Как извлечь все объекты cacertfile с помощью командной строки openssl? Установка пользовательских пакетов в Linux Как скопировать большие файлы на другой Linux Server независимо от TTY iceweasel (firefox) переустановка браузера Проблема мониторинга энергопотребления Каков синтаксис сложного условия в оболочке? Почтовый уведомитель IMAP для оконного менеджера / панели задач?

'ls -1': список имен файлов без расширения

ls -1 перечисляет мои элементы следующим образом:

 foo.png bar.png foobar.png ... 

Я хочу, чтобы он был указан без .png :

 foo bar foobar ... 

(каталог содержит только файлы .png )

Может ли кто-нибудь сказать мне, как использовать grep в этом случае?

Назначение: У меня есть текстовый файл, где все имена перечислены без расширения. Я хочу создать скрипт, который сравнивает текстовый файл с папкой, чтобы увидеть, какой файл отсутствует.

Вам нужна оболочка для этой работы.

POSIXly:

 for f in *.png; do printf '%s\n' "${f%.png}" done 

С zsh :

 print -rl -- *.png(:r) 
 ls -1 | sed -e 's/\.png$//' 

Команда sed удаляет (то есть заменяет пустую строку) любую строку .png найденную в конце имени файла.

. экранируется как \. так что он интерпретируется sed как литерал . а не регулярное выражение . (что означает соответствие любому персонажу). $ – привязка конца строки, поэтому она не совпадает с .png в середине имени файла.

Если вы просто хотите использовать bash:

 for i in *; do echo "${i%.png}"; done 

Вы должны достичь grep при попытке найти совпадения, а не для удаления / замены для этого sed более уместно:

 find . -maxdepth 1 -name "*.png" | sed 's/\.png$//' 

После того, как вы решите, что вам нужно создать несколько подкаталогов для упорядочивания файлов PNG, вы можете легко изменить это:

 find . -name "*.png" | sed 's/\.png$//' 

Я бы пошел на basename (предполагая реализацию GNU):

 basename --suffix=.png -- * 

Другой очень похожий ответ (я удивлен, что этот конкретный вариант еще не появился):

 ls | sed -n 's/\.png$//p' 
  • Вам не нужна опция -1 для ls , так как ls предполагает, что если стандартный вывод не является терминалом (в этом случае это труба).
  • опция -n для sed означает «не печатать строку по умолчанию»
  • параметр /p в конце подстановки означает «… и печатает эту строку, если была сделана замена».

Чистым результатом этого является печать только тех строк, которые заканчиваются на .png , с удаленным .png . То есть, это также связано с небольшим обобщением вопроса OP, где каталог не содержит только .png файлов.

Техника sed -n часто полезна в тех случаях, когда вы могли бы использовать grep + sed.

Для этого вы можете использовать только команды BASH (без каких-либо внешних инструментов).

 for file in *; do echo "${file%.*}"; done 

Это полезно, если у вас нет / usr / bin и работает хорошо для имен файлов, таких как this.is.image.png и для всех расширений.

Небезопасно разбирать ls или find трубку [ 1 , 2 ]

Небезопасно разбирать (и транслировать) вывод ls или find , в основном потому, что в именах файлов можно найти не обычные символы как новую строку , вкладку … Здесь будет работать чистый цикл оболочки [ cuonglm ] ,
Даже команда find не связанная с опцией -exec будет работать:

 find ./*.png -exec basename {} .png \; 

Обновления / Примечания : вы можете использовать find . искать даже для скрытых файлов или find ./*.png чтобы получить только не скрытые файлы. С помощью find *.png -exec ... вас может возникнуть проблема в том случае, если в нем присутствует файл с именем .png потому что find получит его как опцию. Вы можете добавить -maxdepth 0 чтобы избежать спуска в каталогах с именем Dir_01.png или find ./*.png -prune -exec ... когда maxdepth не разрешен (спасибо Stéphane). Если вы хотите не указывать эти каталоги, вы должны добавить параметр -type f (который также исключает другие типы нерегулярных файлов). Посмотрите на man для более полной панорамы обо всех доступных вариантах и ​​не забудьте проверить, совместимы ли они с POSIX, для лучшей переносимости.

Несколько слов больше

Например, если вы копируете заголовок из документа и вставляете его в имя файла, одна или несколько строк новой строки будут завершены в самом имени файла. Нам может быть даже так повезло, что заголовок может содержать даже тот ключ, который мы должны использовать перед новой строкой:

 The new art of working on .png files and other formats. 

Если вы хотите протестировать, вы можете создавать имена файлов, подобные этому, с помощью команд

 touch "A file with two lines"$'\n'"and This is the second.png" touch "The new art of working on .png"$'\n'"files and other formats.png" 

Выйдет простой /bin/ls *png ? вместо непечатаемых символов

 A file with two lines?and This is the second.png The new art of working on .png?files and other formats.png 

Во всех случаях, когда вы будете обрабатывать вывод ls или find следующую команду, не будет никакого намека на то, чтобы понять, соответствует ли текущая строка новому имени файла или соответствует ли символ новой строки в имени файла прецедента. Злобное имя, но все же юридическое.

Будет работать цикл оболочки с оболочкой Parameter-Expansion, ${parameter%word} в обоих вариантах с printf или echo [ cuonglm ], [ Anthon1 ] .

 for f in *.png; do printf "%s\n" "${f%.png}" ; done 

На странице man расширения параметра Shell [ 3 ]

$ {Параметр% слово}
$ {Параметр %% слово}

… результатом расширения является значение параметра с кратчайшим шаблоном соответствия (случай «%») или самый длинный шаблон соответствия (случай «%%»).

не так ли было?

 ls -1 | sed 's/\.png//g' 

или вообще

 ls -1 | sed 's/\.[az]*//g' 

удалит все расширения

Использовать rev :

 ls -1 | rev | cut -f 2- -d "." | rev 

rev меняет все строки (строки); вы режете все после первого ». и rev повторно меняет остатки.

Если вы хотите grep 'alma':

 ls -1 | rev | cut -f 2- -d "." | rev | grep 'alma' 

в соответствии с вашим комментарием «У меня есть текстовый файл, где все имена перечислены без расширения. Я хочу создать скрипт PHP, который сравнивает текстовый файл с папкой, чтобы увидеть, какой файл отсутствует»:

 for file in $(cat yourlist) ; do [ -f "${file}.png" ] || { echo "$file : listed in yourlist, but missing in the directory" } done #assumes that filenames have no space... # otherwise use instead: # while IFS= read file ; do ...(same inner loop as above)... ; done < yourlist 

и наоборот:

 for file in *.png ; do grep "^${file%.png}$" yourlist >/dev/null || { echo "$file: present in the directory but not listed in yourlist" } done #I assume there are no spaces/tabs/? before/after names in 'yourlist'. Change the script accordingly if there are some (or sanitize the list) 

ls -l | sed 's/\.png$//'

Является самым точным методом, который был выделен @roaima. Без экранированных \.png файлов с именем a_png.png будут отображаться как: a_ .

Если бы я знал, что в каталоге есть файлы с .png как расширение, я бы просто запустил: ls | awk -F. '{print $1}' ls | awk -F. '{print $1}'

Это вернет первое «поле» для чего-либо, где есть имя файла.

Пример:

 [rsingh@rule51 TESTDIR]$ ls 10.png 1.png 2.png 3.png 4.png 5.png 6.png 7.png 8.png 9.png [rsingh@rule51 TESTDIR]$ ls | awk -F. '{print $1}' 10 1 2 3 4 5 6 7 8 9 

Простая строка оболочки (ksh, bash или zsh; не тире):

 set -- *.png; printf '%s\n' "${@%.png}" 

Простая функция (без расширения):

 ne(){ set -- *.png; printf '%s\n' "${@%.png}"; } 

Или функция, которая удаляет любое добавленное расширение (png по умолчанию):

 ne(){ ext=${1:-png}; set -- *."$ext"; printf '%s\n' "${@%.${ext}}"; } 

Использовать как:

 ne jpg 

Если вывод является звездочкой * , файл с этим расширением не существует.

Вы можете попробовать следующий фид awk, вывод которого ваш суператор – это «.». и поскольку все ваши файлы будут иметь имя.png, вы печатаете первый столбец:
ls | awk -F"." '{print $1}'

Если у вас есть привязка к sed, это лучше, так как оно будет разделять последнее расширение файла, независимо от того, что это (png, jpg, tiff и т. Д.).

 ls | sed -e 's/\..*$//'