Mam katalogi, których nazwy są znacznikami czasu, podawanymi w milisekundach od 1970-01-01:
1439715011728
1439793321429
1439879712214
.
.
Potrzebuję danych wyjściowych takich jak:
1442039711 Sat Sep 12 08:35:11 CEST 2015
1442134211 Sun Sep 13 10:50:11 CEST 2015
1442212521 Mon Sep 14 08:35:21 CEST 2015
.
.
Mogę wyświetlić wszystkie katalogi według polecenia:
find ./ -type d | cut -c 3-12
Ale nie mogę umieścić danych wyjściowych w następnym poleceniu: date -d @xxxxxx
i manipulować danymi wyjściowymi.
W jaki sposób mogę to zrobić?
Fri Oct 2 05:35:28 47592
)Odpowiedzi:
Jesteś na dobrej drodze (dla prostszego rozwiązania, uruchamiając tylko 2 lub 3 polecenia, patrz poniżej). Powinieneś użyć
*
zamiast./
pozbyć się bieżącego katalogu¹, a to nieco upraszcza wycinanie milisekund, a następnie po prostu przesłać wynik do GNUparallel
lubxargs
²:dostać
i aby dodać przesunięcie sekund przed tym, jak pokazuje przykład:
lub:
uzyskać:
Łatwiej jednak to zrobić:
co daje ci to samo żądane wyjście jeszcze raz.
Wadą używania
*
jest to, że Twój wiersz poleceń ogranicza jego rozszerzenie, jednak zaletą jest sortowanie katalogów według wartości znacznika czasu. Jeśli liczba katalogów stanowi problem, użyj-mindepth 1
, ale stracisz kolejność:i w
sort
razie potrzeby wstaw :¹ Zakłada się, że nie ma zagnieżdżonych podkatalogów, jak wydaje się w przypadku twojego przykładu. Można również użyć
./ -mindepth 1
zamiast*
² można zastąpić
parallel
zxargs -I{}
tutaj jako @hobbs i @don_crissti zasugerował, to po prostu bardziej gadatliwy. ³ na podstawie odpowiedzi Gillesa na wykorzystaniedate
możliwości odczytu plikówźródło
xargs
jeśli nie maszparallel
, czego wiele osób prawdopodobnie nie ma.xargs
nie ma opcji, aby określić, gdzie argument idzie jakparallel
ma z{}
.find ./ -type d | cut -c 3-12 | xargs -I{} date --d @{} +'%Y-%m-%d'
-I
opcji.--d
lub--da
działałby z aktualnymi wersjami GNUdate
, ale może przestać działać dzieńdate
wprowadza--dalek
opcję (dla dat w kalendarzu Dalek).Unikałbym uruchamiania kilku poleceń na plik w pętli. Ponieważ już używasz GNUisms:
Który po prostu uruchamia dwa polecenia.
strftime()
jest specyficzny dla GNU, jakdate -d
.źródło
Już masz:
co prawdopodobnie zapewnia znaczniki czasu w formacie epoki. Teraz dodaj pętlę while:
Zauważ jednak, że w niektórych powłokach ta składnia dostaje pętlę while w podpowłoce, co oznacza, że jeśli spróbujesz ustawić tam zmienną, nie będzie ona widoczna po wyjściu z pętli. Aby to naprawić, musisz lekko odwrócić głowę:
który wstawia
find
podpowłokę i utrzymuje pętlę while w głównej powłoce. Że składnia (AT & Tksh
,zsh
abash
specyficzna) jest potrzebne tylko wtedy, gdy szukasz ponowne wynik od wewnątrz pętli, choć.źródło
done <(find)
zamiastdone < <(find)
tego było poprawne dlayash
(gdzie<(...)
jest przekierowanie procesu, a nie podstawienie procesu), więc moja edycja była nieco bardziej nonszalancka, ponieważ mogła to być powłoka, dla której miałeś to na myśli.Jeśli masz datę GNU, może konwertować daty odczytane z pliku wejściowego. Musisz tylko trochę masować znaczniki czasu, aby mógł je rozpoznać. Po składni wejściowej znacznika czasu opartego na epoce Uniksa
@
następuje liczba sekund, która może zawierać kropkę dziesiętną.źródło
date
odczytu pliku s. To dadate: invalid date ‘@’
ze względu na tłumaczenie bieżącego katalogu (./
). A ponieważ możesz wyrzucić milisekundy, możesz uprościć drugąsed
edycję, aby po prostu upuścić 3 ostatnie znaki. Lub usuń to wszystko i użyjfind * -type d -printf "@%.10f" | date ...
Zrobiłbym to perwersyjnie - podaj listę znaczników czasu:
To daje:
Jeśli chcesz określonego formatu wyjściowego, możesz użyć
strftime
np .:Które zamienić to w jedną wkładkę w rurze:
Ale prawdopodobnie sugerowałbym zamiast tego skorzystanie z
File::Find
modułu i zrobienie tego w Perlu. Jeśli podasz przykładową strukturę katalogu przed jej wycięciem, dam ci przykład. Ale byłoby to coś takiego:źródło
Z
zsh
a strftime wbudowane:zakłada to, że wszystkie nazwy katalogów w bieżącym katalogu są w rzeczywistości epokami.
Możliwe jest dalsze filtrowanie / przetwarzanie pod warunkiem wyjaśnienia, w jaki sposób należy przetworzyć te liczby w twoim przykładzie (wyglądają bardziej jak epoki odpowiadające datom urodzin księżniczki Lei i Luke'a Skywalkera ...) np. Rekurencyjnie szukaj nazw katalogów, które pasują co najmniej 10 cyfr i oblicz datę na podstawie pierwszych 10 cyfr:
źródło
Korzystanie z GNU Parallel:
Jeśli możesz zaakceptować \ t zamiast spacji:
źródło
parallel
jest napisana wperl
. Wydaje się to przesadą, biorąc pod uwagę, żeperl
mastrftime()
operatora. Jakperl -MPOSIX -lpe '$_.=strftime(" %c", localtime substr $_, 2, 10)'
parallel
. IMOparallel
to świetne narzędzie do równoległego wykonywania zadań intensywnie wykorzystujących procesor, ale tak naprawdę nie jest odpowiednie do tego typu zadań.Zwykle polecenie find może być powiązane z dowolnym poleceniem używającym
exec
argumentu.W twoim przypadku możesz to zrobić w następujący sposób:
źródło
Korzystanie z Pythona (jest to możliwie najbardziej wolniejsze rozwiązanie)
daje:
źródło