2012-06-12 13 views
9

Pozwól mi najpierw opisać moją sytuację, pracuję na platformie Linux i mam zbiór .bmp plików, które dodają jeden do numeru zdjęcia od filename0022.bmp do filename0680.bmp. Łącznie 658 zdjęć. Chcę móc uruchomić każdy z tych obrazów poprzez plik .exe, który działa na obrazie, a następnie kopie plik do pliku określonego przez użytkownika, ma również pewne argumenty progowe: niższy, górny. Tak typowe wezwanie do pliku wykonywalnego jest:Jak zapętlić polecenie wykonywalne w terminalu w systemie Linux?

./filter inputfile outputfile lower upper 

Czy istnieje sposób, że mogę pętla to wezwanie nad wszystkimi plikami tylko z terminala lub tworząc pewien rodzaj skryptu bash? Mój problem jest podobny do tego: Execute a command over multiple files with a batch file, ale tym razem pracuję w terminalu wiersza poleceń Linuksa.

Odpowiedz

6

Można spróbować coś takiego ...

#! /bin/bash 
for ((a=022; a <= 658 ; a++)) 
do 
    printf "./filter filename%04d.bmp outputfile lower upper" $a | "sh" 
done 
+1

Oto, co próbowałem i wydrukował kilka drobiazgów na moim ekranie, ale w rzeczywistości nie tworzył żadnych plików ... #!/Bin/atakujących do ((a = 022; a <= 680; a ++)) zrobić printf”./filter płód 00-2.3.5um__voi0% 04d.bmp fetus_threshold_% 04d 90 240" $ a wykonane gdzie 90 i 240 to dolne i górne argumenty, o których wspomniałem wcześniej. Nie stworzyłem skryptu bash, więc użyłem emacsa do utworzenia pliku, w którym wpisałem poprzednie linie kodu. Następnie zapisałem plik emacs po prostu jako test. nic z tym nie wynika, ponieważ właśnie to widziałem kilka przykładów w Internecie. Jakieś dalsze wskazówki? –

+0

spróbuj zrobić to w pliku .sh (z nowym dodatkiem, który zrobiłem powyżej), a następnie uruchom plik, wpisując [[bash myfile.sh]] w tym samym katalogu – scottyaz

+0

Cóż, dobre wieści ... to przynajmniej iteruje to czas dookoła i działa nawet na pierwszym obrazie, wtedy dostaję błędy z oprogramowania, którego używa program. Rzeczą, której nie rozumiem, jest to, że próbuje uruchomić się na inputfile0000 i mówimy, żeby zaczynało się od pliku inputfile0022.bmp. Jedynym obrazem wyjściowym, który otrzymuję, jest plik outputfile0000.bmp. Oto plik basha, który zapisałem jako threshold.sh: #!/bin/bash dla ((a = 022; a <= 680; a ++)) do printf "./filter6 fetus-00-2_3.5um__rec_voi% 04d.bmp fetus_threshold_% 04d.bmp 90 240" $ a | "sh" done –

1

Można przetestować ten AS-IS w swojej powłoce:

for i in *; do 
    echo "$i" | tr '[:lower:]' '[:upper:]' 
done 

Jeśli masz specjalną ścieżkę, zmiany * po ścieżce + glob: Ex:

for i in /home/me/*.exe; do ... 

Zobacz http://mywiki.wooledge.org/glob

+0

zakładając, że jest we właściwym katalogu: =) – ant

+1

redakcją wyjaśnić tę możliwość =) –

+0

hej Sputnick, mógłbyś mi pomóc zrozumieć ten kawałek kodu, który napisałem wyżej? Widzę, że masz pętlę for przechodzącą przez wszystko, ale nie widzisz, gdzie kiedykolwiek wywołasz plik wykonywalny do przetwarzania obrazów. Czy mógłbyś podać mi trochę więcej szczegółów i objaśnień? Dziękuję za pomoc i posty. Wspaniale jest uzyskać tak dużą pomoc w tak krótkim czasie. –

0

Ta opcja powoduje dodanie nazwy obrazów wyjściowych, takich jak filtered_filename0055.bmp

for i in *; do 
    ./filter $i filtered_$i lower upper 
done 
+0

Spowoduje to nadpisanie pliku źródłowego. –

+0

Co jeśli plik zawiera spację? Następnie polecenie rozwiąże plik './filter withspace filtered_file withspace lower upper'. Powinieneś prawdopodobnie zacytować '" $ i "', kiedy go używasz. –

+1

@TimPote Po prostu staram się uczynić to tak prostym, jak to tylko możliwe w oparciu o informacje o pytaniu., Ale tak, cudzysłów sprawi, że będzie lepiej sprawdzać rozszerzenie i katalog plików. –

11

Możesz być zainteresowany patrząc bash skryptów.

Możesz wykonywać polecenia w pętli for bezpośrednio z powłoki.

Prosta pętla do generowania liczb, które wymieniłeś. Na przykład, z powłoki:

[email protected] $ for i in {22..680} ; do 
> echo "filename${i}.bmp" 
> done 

To daje listę z filename22.bmp do filename680.bmp. To po prostu obsługuje iterację zakresu, o którym wspomniałeś. Nie obejmuje to zerowych numerów dopełnienia. Aby to zrobić, możesz użyć printf. Składnia printf to printf format argument. Możemy użyć zmiennej $i z poprzedniej pętli jako argumentu i zastosować format %Wd, gdzie W jest szerokością. Przedrostek symbolu zastępczego W będzie określał znak, który ma być użyty. Przykład:

[email protected] $ for i in {22..680} ; do 
> echo "filename$(printf '%04d' $i).bmp" 
> done 

W powyższych $() działa jako zmiennej wykonywania poleceń, aby uzyskać wartość przeciwieństwie do z góry określonej wartości.

To powinno teraz dać ci nazwy plików, które określiłeś. Możemy przyjąć, że i zastosować go do rzeczywistego zastosowania:

[email protected] $ for i in {22..680} ; do 
> ./filter "filename$(printf '%04d' $i).bmp" lower upper 
> done 

to może być zapisane w jedną linię:

[email protected] $ for i in {22..680} ; do ./filter "filename$(printf '%04d' $i).bmp" lower upper ; done 

Należy zwrócić uwagę od kwestii, pliki .exe są zwykle zestawiane w COFF format, w którym system Linux oczekuje pliku w formacie ELF.

+0

'użytkownik @ maszyna $ 'ma symulować monit powłoki,'> 'symuluje kontynuację zapytania oczekując więcej przed wykonaniem polecenia do wykonania. –

7

tu prosty przykład:

for i in {1..100}; do echo "Hello Linux Terminal"; done 

do dołączania do pliku: (>> służy do dołączania, można również użyć> nadpisać)

for i in {1..100}; do echo "Hello Linux Terminal" >> file.txt; done 
1

Można wykorzystać xargs dla iteracji:

ls | xargs -i ./filter {} {}_out lower upper 

Uwaga:

  • {} odpowiada jednemu liniowemu wynikowi potoku, tutaj jest to nazwa pliku wejściowego.
  • Pliki wyjściowe będą miały nazwę z postfiksem "_out".
Powiązane problemy