Как проверить, пуст ли файл в Bash?

184

У меня есть файл с именем diff.txt. Хотите проверить, если он пуст. Сделал что-то подобное, но не смог заставить его работать.

if [ -s diff.txt ]
then
        touch empty.txt
        rm full.txt
else
        touch full.txt
        rm emtpy.txt
fi
Mich
источник
24
[-s FILE] Истина, если FILE существует и имеет размер больше нуля. Таким образом, вы получите «empty.txt», если «diff.txt» не пустой.
Матиас
2
PS: Если вы хотите проверить фактический diffвызов, просто проверьте возвращаемое значение:if diff foo.txt bar.txt; then echo 'No difference'
l0b0
20
Тест может быть отменен:if [ ! -s diff.txt ]; then echo "IS EMPTY";else echo "HAS SOMETHING";fi
Дэвид Рамирес
Остерегайтесь висячих символов новой строки. Проверьте файл с$ cat diff.txt | hexdump -C
Алехандро Бласко

Ответы:

225

Неправильные написания раздражают, не так ли? Проверьте правильность написания empty, но затем также попробуйте это:

#!/bin/bash -e

if [ -s diff.txt ]
then
        rm -f empty.txt
        touch full.txt
else
        rm -f full.txt
        touch empty.txt
fi

Мне очень нравятся сценарии оболочки, но один из недостатков заключается в том, что оболочка не может помочь вам, когда вы ошибаетесь, тогда как компилятор, такой как ваш компилятор C ++, может вам помочь.

Кстати, обратите внимание, что я поменялся ролями empty.txtи full.txt, как предполагает @Matthias.

THB
источник
6
Оболочка может помочь с ошибками. empty=empty.txt; full=full.txt; diff=diff.txt; if [ -s ${diff?} ]; then r=${empty?} t=${full?}; else r=${full?} t=${empty?}; fi; rm ${r?}; touch ${t?}
Уильям Перселл
1
С помощью инструмента shellcheck можно найти орфографические ошибки просто отлично.
Йокай,
1
Конечно, это не удастся, если файл не существует либо? Предполагается, что это проверка, если файл пуст.
geedoubleya
@geedoubleya: Конечно. Это разумный момент. Если бы существование файла было релевантным (как, конечно, могло бы быть), то можно соответствующим образом настроить скрипт. Если бы вы дали откорректированный сценарий в качестве ответа и обзвонили меня, я бы проголосовал.
THB
1
Вы также можетеset -u
Джон
71
[ -s file.name ] || echo "file is empty"
Микки Уайт
источник
8
[[-s file.name]] && echo "full" || эхо "пусто"
McPeppr
1
[[ -s file.name ]] || { [[ -f file.name ]] && echo 'empty' || echo 'does not exist'; }
умнее
53

[[-s file]] -> Проверяет, имеет ли размер файла больше 0

if [[ -s diff.txt ]]; then echo "file has something"; else echo "file is empty"; fi

При необходимости проверяются все файлы * .txt в текущем каталоге; и сообщает все о пустом файле:

for file in *.txt; do if [[ ! -s $file ]]; then echo $file; fi; done
Surya
источник
3
Вам не нужно делать $(ls *.txt, и на самом деле не должно. У некоторых людей для lsэтого заданы значения по умолчанию (например, я), и оболочка уже будет расширяться *.txtсама по себе. Просто сделай for file in *.txtвместо этого.
Лилит
Ницца! Если вы хотите проверить все txt-файлы рекурсивно, вы можете использовать findэто так:for file in $(find . -name '*.txt'); do if [[ ! -s $file ]]; then echo $file; fi; done
KlimczakM
1
Проголосовал только из-за этого ужасного анти-паттерна for file in $(ls *.txt); do. Пожалуйста, используйте for file in *.txt; doвместо этого; пожалуйста, прочитайте эту страницу Bash Pitfalls ; и, пожалуйста, прекратите распространять антипаттерны, как это.
gniourf_gniourf
8

Хотя остальные ответы верны, использование этой "-s"опции также покажет, что файл пуст, даже если файл не существует.
Добавив эту дополнительную проверку, "-f"чтобы увидеть, существует ли файл первым, мы гарантируем, что результат правильный.

if [ -f diff.txt ]
then
  if [ -s diff.txt ]
  then
    rm -f empty.txt
    touch full.txt
  else
    rm -f full.txt
    touch empty.txt
  fi
else
  echo "File diff.txt does not exist"
fi
geedoubleya
источник
4

@geedoubleya ответ мой любимый.

Тем не менее, я предпочитаю это

if [[ -f diff.txt && -s diff.txt ]]
then
  rm -f empty.txt
  touch full.txt
elif [[ -f diff.txt && ! -s diff.txt ]]
then
  rm -f full.txt
  touch empty.txt
else
  echo "File diff.txt does not exist"
fi
smarber
источник
3

Чтобы проверить, является ли файл пустым или имеет только пробелы , вы можете использовать grep:

if [[ -z $(grep '[^[:space:]]' $filename) ]] ; then
  echo "Empty file" 
  ...
fi
Ноам Манос
источник
Это единственный хороший ответ, и он должен быть принят. Использование -sне отвечает на вопрос. Он ищет файл, который существует и имеет размер более 0 байтов.
Акито
2

Многие из ответов верны, но я чувствую, что они могут быть более полными / упрощенными и т.д., например:

Пример 1: Базовый оператор if

# BASH4+ example on Linux :

typeset read_file="/tmp/some-file.txt"
if [ ! -s "${read_file}" ]  || [ ! -f "${read_file}" ] ;then
    echo "Error: file (${read_file}) not found.. "
    exit 7
fi

если $ read_file пуст или нет, остановите показ с выходом. Я не раз неправильно читал верхний ответ, чтобы обозначить обратное.

Пример 2: как функция

# -- Check if file is missing /or empty --
# Globals: None
# Arguments: file name
# Returns: Bool
# --
is_file_empty_or_missing() {
    [[ ! -f "${1}" || ! -s "${1}" ]] && return 0 || return 1
}
Майк Q
источник
1
[[ -f filename && ! -s filename ]] && echo "filename exists and is empty"
Радек Гоблин Песченка
источник
0

Я пришел сюда в поисках, как удалить пустые __init__.pyфайлы, поскольку они неявно присутствуют в Python 3.3+, и в итоге использовал:

find -depth '(' -type f  -name __init__.py ')' -print0 |
  while IFS= read -d '' -r file; do if [[ ! -s $file ]]; then rm $file; fi; done

Также (по крайней мере, в zsh) использование $ path в качестве переменной также нарушает вашу среду $ PATH и, таким образом, разрушает вашу открытую оболочку. Во всяком случае, думал, что я поделюсь!

SamMorrowDrums
источник
0

Самый простой способ проверить, файл пуст или нет:

if [ -s /path-to-file/filename.txt ]
then
     echo "File is not empty"
else
     echo "File is empty"
fi

Вы также можете написать это в одной строке:

[ -s /path-to-file/filename.txt ] && echo "File is not empty" || echo "File is empty"
Набиль Шейх
источник