Назад | Перейти на главную страницу

Как вырезать расширение из имени пути с помощью основных инструментов unix

Мне нужно собрать список файлов и поместить его в текстовый файл. Однако файлы не должны иметь расширение.

Теперь у меня есть команда без удаления расширений файлов:

ls -1 /a/dir/*/dir/* > textfile

Все выбранные файлы будут иметь расширение. [A-z] {3}

(причина, по которой мне это нужно, в том, что мне нужен список уникальных базовых имен, и unique решит это после этого шага)

Что-то в этом роде перечислит файл в текущем каталоге, удалив все после первой точки.

find . -maxdepth 1 -type f | xargs -iZ basename Z | cut -d"." -f1 > /tmp/resultfile

В конечном итоге у него возникнет проблема со скрытыми файлами, что приведет к пустой строке в файле результатов. Базовое имя здесь только для того, чтобы избавиться от "./", начинающегося с имен файлов в найти результат.

Мне всегда нравится включать решение только для bash:

for file in /a/dir/*/dir/*; do
    echo "${file%.*}" >> ~/file_list
done

и с необязательным оператором if, чтобы ограничить файл запрошенным расширением:

shopt -s extglob
for file in /a/dir/*/dir/*; do
    if [[ "$file" =~ \.[a-zA-Z]{3}$ ]]; then
        echo "${file%.*}" >> ~/file_list
    fi
done

В эта похожая ошибка сервера вопрос Объясняю расширение параметра "$ {file%. *}".

Как насчет:

ls -1 /a/dir/*/dir/* | sed -e 's/\.[a-zA-Z0-9]\{3\}$//'

Делай, что хочешь.

Это намного проще, чем кажется:

asd@locutus:~$ IZE=file.avi
asd@locutus:~$ echo $IZE
file.avi
asd@locutus:~$ echo ${IZE%%.???}
file
asd@locutus:~$ 

Итак, таким образом:

ls -1 /a/dir/*/dir/* | while read VAR; do echo ${VAR%.???}; done

Между do и done вы можете делать все, что хотите, echo - всего лишь пример.

man bash (расширение параметра):

   ${parameter%%word}
          The word is expanded to produce a pattern just as in pathname  expansion.
          If the pattern matches a trailing portion of the expanded value of param‐
          eter, then the result of the expansion is the expanded value of parameter
          with the shortest matching pattern (the ‘‘%’’ case) or the longest match‐
          ing pattern (the ‘‘%%’’ case) deleted.  If parameter is @ or *, the  pat‐
          tern  removal  operation is applied to each positional parameter in turn,
          and the expansion is the resultant list.  If parameter is an array  vari‐
          able subscripted with @ or *, the pattern removal operation is applied to
          each member of the array in turn, and  the  expansion  is  the  resultant
          list.

Более общий ответ, находит расширения любой длины:

find . -type f | sed 's/^.*\.\([^.]*\)$/\1/'

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

find . -type f | sed 's/^.*\.\([^.]*\)$/\1/' | sort | uniq -c | sort -n

Вы также можете использовать разрез следующим образом:

for file in /a/dir/*/dir/* ; do
  echo \`echo $file | cut -d"." -f 1` >> textfile;
done

Это будет работать только в том случае, если у вас нет файлов или каталогов с "." во имя

Вы дали явное определение расширений,
Но теги linux и bash-scripting предложить среду unix.
Если вы не делаете это с Cygwin в Windows.
В этом случае эти моменты могут не иметь значения ...

  • Убедитесь, что в вашем «добавочном номере» нет номеров (например, md5)
  • Кроме того, как насчет расширений, содержащих менее 3 символов? (script.sh)
  • А как насчет расширений с заглавными буквами?