Czy istnieje sposób, aby zmusić gzip do nie zastępowania plików w przypadku konfliktu?

17

Piszę skrypt, w którym zgrywam pliki.

Istnieje możliwość spakowania pliku, utworzenia pliku o tej samej nazwie i spróbowania go również zgzipować, np.

$ ls -l archive/
total 4
-rw-r--r-- 1 xyzzy xyzzy  0 Apr 16 11:29 foo
-rw-r--r-- 1 xyzzy xyzzy 24 Apr 16 11:29 foo.gz

$ gzip archive/foo
gzip: archive/foo.gz already exists; do you wish to overwrite (y or n)? n   
    not overwritten

Używając gzip --force, mogę zmusić gzip do zastąpienia foo.gz, ale w tym przypadku myślę, że istnieje duża szansa, że ​​stracę dane, jeśli nadpisam foo.gz. Wydaje się, że nie ma przełącznika wiersza poleceń, który zmusiłby gzip do pozostawienia .gzplików w spokoju ... nieinteraktywna wersja naciskania 'n' po znaku zachęty.

Próbowałem gzip --noforcei gzip --no-forcemając nadzieję, że będą one zgodne ze standardem opcji GNU, ale żadne z nich nie zadziałało.

Czy istnieje proste obejście tego problemu?

Edytować:

Okazuje się, że jest to jeden z czasów, w których opłaca się czytać stronę informacyjną, a nie stronę podręcznika.

Ze strony informacyjnej:

`--force'
`-f'
     Force compression or decompression even if the file has multiple
     links or the corresponding file already exists, or if the
     compressed data is read from or written to a terminal.  If the
     input data is not in a format recognized by `gzip', and if the
     option `--stdout' is also given, copy the input data without
     change to the standard output: let `zcat' behave as `cat'.  If
     `-f' is not given, and when not running in the background, `gzip'
     prompts to verify whether an existing file should be overwritten.

Na stronie podręcznika brakowało tekstu, a gdy nie działał w tle

Podczas działania w tle gzip nie wyświetli monitu i nie zastąpi, chyba że -fzostanie wywołana opcja.

Barton Chittenden
źródło
3
Nie jestem pewien, jak gzip sprawdza, czy jesteś w tle, ale dodawanie „&” w bash w systemie, nad którym pracuję, nie robi tego. Wydaje się, że bycie po drugiej stronie rury działa, więc zamiast: find ./ ! -name "*gz" -exec gzip {} \; & działa: find ./ ! -name "*gz" -print0 | xargs -0 -n 1 -t gzip gzip zgłasza: gzip: ./2012-July.txt.gz already exists; not overwritten
Bill McGonigle
1
@BillMcGonigle Twój komentarz powinien być odpowiedzią!
Rockallite,

Odpowiedzi:

9

Przyszło mi do głowy, że najlepszym sposobem na uniknięcie niepożądanego efektu jest nie proszenie programu o wykonanie niepożądanego efektu. Oznacza to, że po prostu nie każ mu kompresować pliku, jeśli plik jest już w formie skompresowanej.

na przykład:

if [ ! -f "$file.gz" ]; then 
    gzip "$file"; 
else 
    echo "skipping $file"
fi

lub krótszy (uruchom, truejeśli istnieje plik.gz, w innym przypadku skompresuj plik)

[ -f "$file.gz" ] && echo "skipping $file" || gzip "$file"    
Ярослав Рахматуллин
źródło
Niestety jest to uruchamiane jako polecenie systemowe w skrypcie perla (długa historia o tym, dlaczego nie używamy czegoś takiego jak IO :: Compress :: Gzip, zaufaj mi, pomyślałem o tym). Samo polecenie kompresji jest przechowywane w pliku konfiguracyjnym. Twoje ostatnie polecenie wydaje się zbliżone do tego, czego potrzebuję, ale myślę, że znalazłem coś, co nieco lepiej spełni moje potrzeby. Przyjmuję twoją odpowiedź, ponieważ jest to lepsze ogólne rozwiązanie niż moje, ale zobacz poniżej, czego właściwie użyję.
Barton Chittenden
Możesz szturchnąć plik w Perlu ...
Ррослав Рахматуллин
1
Nie jestem pewien, o co ci chodzi poke a file.
Barton Chittenden
Brak skojarzeń / wykorzystywania wizerunku w codziennej komunikacji w amerykańskim angielskim zaskakuje mnie za każdym razem :) Pozwólcie, że spróbuję wyjaśnić. Przywołaj obraz dziecka szturchającego patyk martwego kruka, aby zobaczyć, czy żyje, czy nie. Grzebanie służy tutaj do sprawdzania atrybutów . Podobnie, szturchanie pliku oznaczałoby sprawdzenie czegoś, na przykład, czy w ogóle jest obecne. W każdym razie, ja czuję akt wywiercenie powinien przynajmniej średni „osiągnąć kontakt z zewnętrzną obiektu” , i że wystarczy powiedzieć „uzyskać pewne informacje o pliku” z obrazem, zamiast pisowni go.
Ярослав Рахматуллин
„poke” to często hakerski slang określający lokalizację pamięci. Zobacz: en.wikipedia.org/wiki/PEEK_and_POKE#Generic_usage_of_.22POKE.22
Bill McGonigle
12

Najbliższa rzecz, jaką mogłem znaleźć dla pojedynczego polecenia, to:

yes n | gzip archive/foo

W yeskomenda yobserwowani przez LineFeed powinien mieć standardowe wyjście, dopóki nie otrzyma sygnału. Jeśli ma argument, wypisze go zamiast y. W takim przypadku drukuje ndo momentu wyjścia gzip, zamykając w ten sposób potok.

Jest to odpowiednik nwielokrotnego wprowadzania na klawiaturze; to automatycznie odpowie na pytaniegzip: archive/foo.gz already exists; do you wish to overwrite (y or n)?

Ogólnie myślę, że lepiej nie próbować kompresować plików, jeśli istnieje odpowiedni plik gzip; moje rozwiązanie jest głośniejsze, ale odpowiada moim szczególnym potrzebom zastępczego gzippolecenia, siedząc w pliku konfiguracyjnym.

Barton Chittenden
źródło
1
kolejną irytacją jest to, że gzipwychodzi2
Steven Penny,