Избегайте перечисления файлов, которые заканчиваются на ~ (резервные файлы)

20

Мое требование - перечислить все файлы в каталоге, кроме файлов, заканчивающихся на ~ (резервные файлы).

Я пытался использовать команду:

ls -l | grep -v ~    

Я получаю этот вывод:

asdasad
asdasad~
file_names.txt
normaltest.txt
target_filename
testshell1.sh
testshell1.sh~
testshell2.sh
testshell2.sh~
testtwo.txt
testtwo.txt~
test.txt
test.txt~

Я хочу получить только эти файлы:

asdasad
file_names.txt
normaltest.txt
target_filename
testshell1.sh
testshell2.sh
testtwo.txt
test.txt
curious_one
источник
Похоже, вы пытаетесь избежать перечисления файлов, которые заканчиваются на ~. Эти файлы являются файлами резервных копий, созданных некоторыми текстовыми редакторами.
Ctrl-Alt-Delor
Какую операционную систему вы используете: это Gnu / Linux (например, Debian, Ubuntu, Redhat, Centos, Fedora, Suse, Mint, Arch,…)?
Ctrl-Alt-Delor
2
Обратите внимание, что файл, который вы хотите игнорировать, похоже, является файлом резервной копии Emacs. Поведение Emacs довольно легко изменить, чтобы он сохранял резервные копии в централизованном каталоге, а не везде; см. emacs.stackexchange.com/questions/33/…
Килиан Фот,
Извините за грубость, но я вам не верю; ls -l(буква ell) будет включать разрешения, ссылки, владельца, размер и время модификации для каждого файла в списке. Вывод, который вы выводите ls -1(цифра 1), и во многих системах -1необходим для вывода на терминал одного столбца , но когда lsон передается по каналу (как здесь grep) или не перенаправляется, -1он не нужен, это уже один столбец ,
dave_thompson_085
@ dave_thompson_085 Я обрезал весь текст и только имена файлов здесь .. Потому что я чувствовал, что это не имеет значения. А также это производственная система (не моя собственная система). Поэтому я не хочу перечислять имена пользователей, детали и пропускать их.
curious_one

Ответы:

49
ls -l | grep -v ~

Причина, по которой это не работает, заключается в том, что тильда расширяется до вашего домашнего каталога, поэтому grepникогда не видит буквальную тильду. (См., Например , руководство Bash по расширению Tilde .) Вам нужно процитировать его, чтобы предотвратить расширение, т.е.

ls -l | grep -v "~"

Конечно, это все равно удалит все выходные строки с тильдой в любом месте, даже в середине имени файла или в другом месте в lsвыходных данных (хотя, вероятно, оно не появится в именах пользователей, датах и ​​т. Д.). Если вы действительно хотите игнорировать файлы, заканчивающиеся тильдой, вы можете использовать

ls -l | grep -v "~$"
ilkkachu
источник
48

Реализация GNU ls(встречается в большинстве систем Linux) имеет опцию для этого: -BИгнорировать резервные копии:

ls --ignore-backups
hschou
источник
24

Если вы используете bash, убедитесь, что extglobон включен:

shopt -s extglob

Тогда вы можете использовать:

ls -d -- !(*~)
  • -d не показывать содержимое каталогов
  • !(*~) все файлы, кроме тех, которые заканчиваются на ~

В zsh вы можете сделать то же самое с kshglobопцией или с помощью собственных расширенных глобусов:

setopt extended_glob
ls -d -- ^*~

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

ls -d -- *[^~]

Но общая идея заключается в использовании ls --ignore-backups.

Ravexina
источник
12

Это должно помочь:

ls -l | grep -v '~'  

Причина: символ ~ заменяется вашим домашним каталогом перед выполнением команды. Пытаться

echo ~

а также

echo '~'
Нико Миттенцвей
источник
6

Как упоминалось в других ответах, причина того, что у вас, вероятно, возникли проблемы, заключается в том, что вы не цитировали и не избежали тильды.

Для одного конкретного случая использования я использовал расширение имени файла оболочки, чтобы сделать нечто подобное. Я использую его примерно с 2003 года, что означает, что он работал с очень широким спектром реализаций оболочки в различных типах систем. (здесь я также использую, -Cпотому что я хочу хорошее отображение в отсортированных столбцах)

ls -C *[!~]

(ограничение при использовании расширения имени файла оболочки, разумеется, заключается в том, что каталог с очень большим количеством (не резервных) файлов приведет к тому, что расширение превысит доступный размер списка аргументов, хотя в большинстве современных систем этот предел довольно высок, часто 250КБ или больше, иногда намного больше)

Грег А. Вудс
источник
1

ls | grep -v '~$'это быстрое решение. Он использует ls для вывода списка всех (не скрытых) файлов, затем использует grep с -v(инвертированное соответствие, т.е. исключение), чтобы исключить все строки с тильдой ( ~) в конце ( $).

ОДНАКО, если у вас есть ЛЮБЫЕ файлы, названные как-то1, что-то2, это ОГРОМНЫЙ вонючий индикатор того, что у вас плохой рабочий процесс, который вы должны исправить в исходном коде, а не с неуклюжими взломами, такими как изменение работы ls.

Если вы обнаружите, что называете файлы номерами версий, такими как test1 и test2 или testone и testtwo, то вам действительно нужна система контроля версий git.

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

Системы контроля версий позволяют вам по существу накладывать временное окно на файловую систему, поэтому вы видите только один testфайл, но под капотом (через программу контроля версий) все версии доступны для поиска, извлечения, возврата, сравнения и т. Д. ,

После того, как вы это настроите, вам больше не нужны файлы резервных копий из вашего редактора, потому что контроль версий хранит историю файлов с тех пор, как вы начали ее использовать, даже если с тех пор вы внесли тысячу изменений. Вы даже можете «ветвить» хронологию истории, опробовать новую идею и вернуться назад во времени, а затем, если нужно, попробовать другую идею.

пожалуйста, удалите меня
источник
1

Хотя многие ответы верны (особенно мне нравится этот @Foon), я хотел бы отметить, что получение списка имен с ls -lнекоторыми затруднениями по разным причинам.

Неудивительно, что правильным инструментом для поиска файлов является find.

Одним из его преимуществ является то, что он может самостоятельно обрабатывать «логику выбора», например:

$ find . -maxdepth 1 \( -type f -a \! -name '*~' \) -print

который буквально говорит find:

  1. Ищите файлы в текущем каталоге: .
  2. Ищите их только на уровне этого каталога, то есть не повторяйте: -maxdepth 1
  3. Там ищите сущности, которые

    • типа файла: -type f
    • и: -a
    • чьи имена не заканчиваются на ~: ! -name *~ (где !отрицает следующую директиву, которая соответствует именам файлов, -name *~).

    (Чтобы все совпадение по типу и имени отображалось как логическая единица, его нужно заключить в скобки (и) ).

  4. Выдавать имя каждого найденного файла: -print.

Вы должны защитить некоторые символы, которые являются специальными для оболочки, от интерпретации оболочкой, и поэтому скобки и удар, !экранированы обратной косой чертой, а шаблон имени заключен в *~одинарные кавычки.

Команда findобладает очень мощным мини-языком благодаря использованию его параметров. Например, может быть предложено рекурсивно обрабатывать все дерево файловой системы (или деревья), но при сканировании пропустить определенные каталоги. Можно сопоставить несколько атрибутов файлов - например, время создания или изменения или размер чего угодно.

kostix
источник