Jak sprawdzić, czy plik jest pusty w Bash?

183

Mam plik o nazwie diff.txt. Chcesz sprawdzić, czy jest pusty. Zrobiłem coś takiego, ale nie mogłem tego uruchomić.

if [ -s diff.txt ]
then
        touch empty.txt
        rm full.txt
else
        touch full.txt
        rm emtpy.txt
fi
Mich
źródło
24
[-s PLIK] Prawda, jeśli PLIK istnieje i ma rozmiar większy niż zero. Otrzymasz „empty.txt”, jeśli „diff.txt” nie jest pusty.
Matthias
2
PS: Jeśli chcesz sprawdzić rzeczywiste diffpołączenie, po prostu sprawdź wartość zwrotu:if diff foo.txt bar.txt; then echo 'No difference'
l0b0
20
Test można zanegować:if [ ! -s diff.txt ]; then echo "IS EMPTY";else echo "HAS SOMETHING";fi
David Ramirez
Uważaj na końcowe znaki nowej linii. Sprawdź plik za pomocą$ cat diff.txt | hexdump -C
Alejandro Blasco

Odpowiedzi:

225

Błędy w pisowni są irytujące, prawda? Sprawdź pisownię empty, ale spróbuj także:

#!/bin/bash -e

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

Bardzo lubię pisać w skryptach powłoki, ale jedną wadą jest to, że powłoka nie może ci pomóc, gdy piszesz źle, podczas gdy kompilator taki jak kompilator C ++ może ci pomóc.

Zauważ, nawiasem mówiąc, że zamieniłem się rolami empty.txti full.txt, jak sugeruje @Matthias.

thb
źródło
6
Powłoka może pomóc w pisowni. 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?}
William Pursell
1
Za pomocą narzędzia shellcheck można dobrze znaleźć błędy ortograficzne.
Yokai
1
Z pewnością to się nie powiedzie, jeśli plik też nie istnieje? To ma być sprawdzenie, czy plik jest tylko pusty.
geedoubleya
@geedoubleya: Jasne. To rozsądny punkt. Gdyby istnienie pliku było istotne (jak oczywiście może być), można odpowiednio dostosować skrypt. Jeśli podasz skorygowany skrypt jako odpowiedź i wyślesz ping do mnie, głosuję.
thb
1
Możesz takżeset -u
Jon McClung,
70
[ -s file.name ] || echo "file is empty"
Mickey White
źródło
8
[[-s nazwa_pliku]] && echo „full” || echo „pusty”
McPeppr
1
[[ -s file.name ]] || { [[ -f file.name ]] && echo 'empty' || echo 'does not exist'; }
smarber
53

[[-s plik]] -> Sprawdza, czy plik ma rozmiar większy niż 0

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

W razie potrzeby sprawdzane są wszystkie pliki * .txt w bieżącym katalogu; i zgłasza cały pusty plik:

for file in *.txt; do if [[ ! -s $file ]]; then echo $file; fi; done
Surya
źródło
3
Nie musisz tego robić $(ls *.txt, a właściwie nie powinieneś. Niektóre osoby mają ustawione wartości domyślne, lsktóre używają długiego formatu (jak ja), a powłoka sama się już rozszerza *.txt. Po prostu zrób to for file in *.txtzamiast tego.
Lilith
Miły! Jeśli chcesz sprawdzić rekurencyjnie wszystkie pliki txt, możesz użyć findtego w następujący sposób:for file in $(find . -name '*.txt'); do if [[ ! -s $file ]]; then echo $file; fi; done
KlimczakM
1
Przegłosowano tylko z powodu tego okropnego anty-wzoru for file in $(ls *.txt); do. for file in *.txt; doZamiast tego użyj ; przeczytaj tę stronę Bash Pitfalls ; i proszę, przestańcie rozprzestrzeniać takie anty-wzory.
gniourf_gniourf
8

Podczas gdy inne odpowiedzi są poprawne, użycie tej "-s"opcji spowoduje również, że plik jest pusty, nawet jeśli plik nie istnieje.
Dodając tę ​​dodatkową kontrolę, "-f"aby sprawdzić, czy plik istnieje jako pierwszy, upewniamy się, że wynik jest poprawny.

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
źródło
4

Odpowiedź @geedoubleya jest moją ulubioną.

Jednak wolę to

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
źródło
3

Aby sprawdzić, czy plik jest pusty lub ma tylko białe znaki , możesz użyć grep:

if [[ -z $(grep '[^[:space:]]' $filename) ]] ; then
  echo "Empty file" 
  ...
fi
Noam Manos
źródło
To jedyna dobra odpowiedź i powinna być zaakceptowana. Korzystanie -snie odpowiada na pytanie. Wyszukuje plik, który istnieje i ma rozmiar większy niż 0 bajtów.
Akito
2

Wiele odpowiedzi jest poprawnych, ale wydaje mi się, że mogą być bardziej kompletne / uproszczone itp. Na przykład:

Przykład 1: Podstawowa instrukcja 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

jeśli $ read_file jest pusty lub nie, zatrzymaj pokaz z wyjściem. Niejednokrotnie źle odczytałem tutaj najważniejszą odpowiedź, która oznaczała coś wręcz przeciwnego.

Przykład 2: Jako funkcja

# -- 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
}
Mike Q
źródło
1
[[ -f filename && ! -s filename ]] && echo "filename exists and is empty"
Radek „Goblin” Pieczonka
źródło
0

Przybyłem tutaj, aby usunąć puste __init__.pypliki, ponieważ są one niejawne w Pythonie 3.3+, i skończyłem na użyciu:

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

Również (przynajmniej w zsh) użycie $ path, ponieważ zmienna również psuje env $ PATH, a zatem rozbije twoją otwartą powłokę. W każdym razie, pomyślałem, że podzielę się!

SamMorrowDrums
źródło
0

Najłatwiejszy sposób sprawdzenia pliku jest pusty lub nie:

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

Możesz także napisać to w jednym wierszu:

[ -s /path-to-file/filename.txt ] && echo "File is not empty" || echo "File is empty"
Nabeel Shaikh
źródło