Powiedz, mam plik foo.txt
określający N
argumenty
arg1
arg2
...
argN
które muszę przekazać do polecenia my_command
Jak używać wierszy pliku jako argumentów polecenia?
Powiedz, mam plik foo.txt
określający N
argumenty
arg1
arg2
...
argN
które muszę przekazać do polecenia my_command
Jak używać wierszy pliku jako argumentów polecenia?
Odpowiedzi:
Jeśli twoja powłoka to bash (między innymi), skrót do
$(cat afile)
to$(< afile)
, więc napiszesz:Udokumentowane na stronie podręcznika bash w sekcji „Zastępowanie poleceń”.
Alternatywnie, poproś o odczytanie polecenia ze stdin, więc:
mycommand < file.txt
źródło
<
operatora. Oznacza to, że sama powłoka wykona przekierowanie, a nie wykonacat
plik binarny ze względu na swoje właściwości przekierowania."$(…)"
tego zawartośćfile.txt
byłaby przekazywana na standardowe wejście programumycommand
, a nie jako argument."$(…)"
oznacza uruchomienie polecenia i zwrócenie wyniku w postaci łańcucha ; tutaj „polecenie” czyta tylko plik, ale może być bardziej złożone.Jak już wspomniano, możesz użyć lewych apostrofów lub
$(cat filename)
.To, o czym nie wspomniano, i myślę, że jest to ważne, to fakt, że musisz pamiętać, że powłoka rozbije zawartość tego pliku według białych znaków, podając każde znalezione słowo jako argument do polecenia. I chociaż możesz być w stanie ująć argument wiersza poleceń w cudzysłów, tak aby mógł zawierać spacje, sekwencje specjalne itp., Czytanie z pliku nie da tego samego. Na przykład, jeśli twój plik zawiera:
argumenty, które otrzymasz, to:
Jeśli chcesz pobrać każdy wiersz jako argument, użyj konstrukcji while / read / do:
źródło
read -r
chyba że chcesz rozwinąć sekwencje ucieczki odwrotnym ukośnikiem - a NUL jest bezpieczniejszym separatorem niż nowa linia, szczególnie jeśli argumenty, które przekazujesz, to takie rzeczy jak nazwy plików, które mogą zawierać dosłowne znaki nowej linii. Ponadto bez czyszczenia IFS otrzymujesz początkowe i końcowe białe znaki niejawnie usuwane zi
.przekaże zawartość pliku do polecenia na stdin, ale usunie znaki nowej linii, co oznacza, że nie możesz iterować po każdej linii osobno. W tym celu możesz napisać skrypt z pętlą 'for':
Lub (wariant wieloliniowy):
Lub (wariant wieloliniowy z
$()
zamiast``
):Bibliografia:
źródło
< file
odwrotnych znaków oznacza, że w rzeczywistości w ogóle nie wykonuje przekierowaniacommand
.command `< file`
Nie działa ani w bashu, ani w POSIX sh; zsh to inna sprawa, ale nie o to chodzi w tym pytaniu).Hello World
w jednej linii. Zobaczysz go najpierw uruchomićsome_command Hello
, a następniesome_command World
, niesome_command "Hello World"
bądźsome_command Hello World
.Robisz to za pomocą grawitacji:
źródło
echo "Hello * Starry * World" > file.txt
w pierwszym etapie, można uzyskać co najmniej cztery oddzielne argumenty przekazywane do drugiego polecenia - i prawdopodobnie więcej, ponieważ*
s rozwiną się do nazw plików obecnych w bieżącym katalogu.fork()
wychodzi z podpowłoki z FIFO dołączonym do jej/bin/cat
standardowego wyjścia , a następnie wywołuje jako element potomny tej podpowłoki, a następnie odczytuje wynik przez FIFO; porównaj z$(<file.txt)
, który wczytuje zawartość pliku bezpośrednio do basha, bez użycia podpowłok lub FIFO.Jeśli chcesz to zrobić w niezawodny sposób, który działa dla każdego możliwego argumentu wiersza poleceń (wartości ze spacjami, wartości ze znakami nowej linii, wartości ze znakami cudzysłowu, wartości niedrukowalne, wartości ze znakami glob, itp.), Dostaje trochę bardziej interesujące.
Aby zapisać do pliku, mając tablicę argumentów:
... zastąpić
"argument one"
, odpowiednio"argument two"
, itp.Aby czytać z tego pliku i używać jego zawartości (w bash, ksh93 lub innej niedawnej powłoce z tablicami):
Aby czytać z tego pliku i używać jego zawartości (w powłoce bez tablic; zwróć uwagę, że spowoduje to nadpisanie lokalnej listy argumentów wiersza poleceń, a zatem najlepiej zrobić to wewnątrz funkcji, tak aby nadpisywać argumenty funkcji, a nie lista globalna):
Zauważ, że
-d
(zezwalanie na użycie innego separatora końca linii) jest rozszerzeniem innym niż POSIX, a powłoka bez tablic również może go nie obsługiwać. W takim przypadku może być konieczne użycie języka innego niż powłoka, aby przekształcić zawartość rozdzielaną wartością NUL do postacieval
bezpiecznej:źródło
Oto jak przekazuję zawartość pliku jako argument do polecenia:
źródło
$(<bar.txt)
(przy użyciu powłoki, takiej jak bash, z odpowiednim rozszerzeniem).$(<foo)
jest przypadkiem specjalnym: w przeciwieństwie do zwykłego podstawiania poleceń, jak jest używane w$(cat ...)
, nie rozwidla podpowłoki do wykonywania operacji, a tym samym unika dużego narzutu.Jeśli wszystko, co musisz zrobić, to włączyć plik
arguments.txt
z zawartościąna
my_command arg1 arg2 argN
czym można po prostu użyćxargs
:W
xargs
wywołaniu możesz umieścić dodatkowe argumenty statyczne , takie jakxargs -a arguments.txt my_command staticArg
which will callmy_command staticArg arg1 arg2 argN
źródło
W mojej powłoce bash działało jak urok:
gdzie plik_wejściowy to
Jak widać, pozwala to na wykonanie wielu poleceń w każdym wierszu z pliku input_file, niezła sztuczka, której się tutaj nauczyłem .
źródło
$(somecommand)
, polecenie zostanie wykonane, a nie przekazane jako tekst. Podobnie>/etc/passwd
zostanie przetworzone jako przekierowanie i nadpisanie/etc/passwd
(jeśli uruchomione z odpowiednimi uprawnieniami) itp.xargs -d $'\n' sh -c 'for arg; do command1 "$arg"; command2 "arg"; command3 "arg"; done' _
- a także bardziej wydajne, ponieważ przekazuje jak najwięcej argumentów do każdej powłoki, zamiast uruchamiać po jednej powłoce w każdym wierszu pliku wejściowego.cat
Po kilkukrotnym edytowaniu odpowiedzi @Wesley Rice zdecydowałem, że moje zmiany stały się zbyt duże, aby kontynuować zmianę jego odpowiedzi zamiast pisać własną. Więc zdecydowałem, że muszę napisać własne!
Przeczytaj każdą linię pliku i wykonuj na niej linijka po linii w następujący sposób:
Pochodzi bezpośrednio od autora Vivek Gite tutaj: https://www.cyberciti.biz/faq/unix-howto-read-line-by-line-from-file/ . Dostaje kredyt!
A teraz, aby odpowiedzieć na to teraz zamknięte pytanie, które też miałem: Czy jest możliwe dodanie listy plików z pliku za pomocą polecenia git? - oto moja odpowiedź:
Zauważ, że
FILES_STAGED
jest to zmienna zawierająca bezwzględną ścieżkę do pliku, który zawiera kilka linii, gdzie każda linia jest ścieżką względną do pliku, na którym chciałbym to zrobićgit add
. Ten fragment kodu wkrótce stanie się częścią pliku „eRCaGuy_dotfiles / possible_scripts / sync_git_repo_to_build_machine.sh” w tym projekcie, aby umożliwić łatwą synchronizację tworzonych plików z jednego komputera (np. Komputera, na którym koduję ) z innym (np. mocniejszy komputer, na którym buduję): https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles .Bibliografia:
Związane z:
git add
na nim: Czy jest możliwe dodanie listy plików z pliku za pomocą polecenia git?źródło