Jak uruchomić polecenie dla każdej linii pliku?
Na przykład, w tej chwili używam następujących plików, aby zmienić kilka ścieżek uniksowych, które napisałem do pliku:
cat file.txt | while read in; do chmod 755 "$in"; done
Czy istnieje bardziej elegancki i bezpieczniejszy sposób? 8 answers
Jeśli Twój plik nie jest zbyt duży i wszystkie pliki mają dobrze nazwane (bez spacji lub innych znaków specjalnych, takich jak cudzysłowy), możesz po prostu:
chmod 755 $(<file.txt)
Jeśli masz znaki specjalne i / lub wiele linii w file.txt
.
xargs -0 chmod 755 < <(tr \\n \\0 <file.txt)
Jeśli Twoje polecenie musi być uruchomione dokładnie 1 raz przez wpis:
xargs -0 -n 1 chmod 755 < <(tr \\n \\0 <file.txt)
Nie jest to potrzebne dla tej próbki, ponieważ chmod
akceptuje wiele plików jako argument, ale to pasuje do tytułu pytania.
W jakimś szczególnym przypadku, można nawet zdefiniować lokalizacja argumentu pliku w poleceniach generowanych przez xargs
:
xargs -0 -I '{}' -n 1 myWrapper -arg1 -file='{}' wrapCmd < <(tr \\n \\0 <file.txt)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-10 07:32:24
Tak.
while read in; do chmod 755 "$in"; done < file.txt
W ten sposób można uniknąć cat
procesu.
cat
jest prawie zawsze złe dla takiego celu jak ten. Możesz przeczytać więcej o bezużyteczne użycie Cat.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-08 11:10:46
Jeśli wiesz, że nie masz żadnych białych znaków na wejściu:
xargs chmod 755 < file.txt
Jeśli w ścieżkach mogą być białe spacje i jeśli masz GNU xargs:
tr '\n' '\0' < file.txt | xargs -0 chmod 755
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-18 23:54:35
Jeśli masz ładny selektor (na przykład all .pliki txt w katalogu) można zrobić:
for i in *.txt; do chmod 755 "$i"; done
Lub twój wariant:
while read line; do chmod 755 "$line"; done <file.txt
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-18 18:49:03
Jeśli chcesz uruchomić polecenie równolegle dla każdej linii możesz użyć GNU Parallel
parallel -a <your file> <program>
Każda linia Twojego pliku zostanie przekazana do programu jako argument. Domyślnie parallel
uruchamia tyle wątków, ile liczą Twoje Procesory. Ale można go określić za pomocą -j
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-21 18:02:10
Widzę, że otagowałeś Basha, ale Perl też byłby dobrym sposobem na to:
perl -p -e '`chmod 755 $_`' file.txt
Możesz również zastosować Wyrażenie regularne, aby upewnić się, że otrzymujesz odpowiednie pliki, np. tylko przetwarzać .pliki txt:
perl -p -e 'if(/\.txt$/) `chmod 755 $_`' file.txt
Aby wyświetlić podgląd tego, co się dzieje, wystarczy zastąpić backticki podwójnymi cudzysłowami i dodać print
:
perl -p -e 'if(/\.txt$/) print "chmod 755 $_"' file.txt
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-18 18:49:37
Możesz również użyć AWK, który może dać ci większą elastyczność obsługi pliku
awk '{ print "chmod 755 "$0"" | "/bin/sh"}' file.txt
Jeśli plik ma separator pól w postaci:
Field1, field2, field3
Aby uzyskać tylko pierwsze pole, które wykonasz
awk -F, '{ print "chmod 755 "$1"" | "/bin/sh"}' file.txt
Możesz sprawdzić więcej szczegółów na temat dokumentacji GNU https://www.gnu.org/software/gawk/manual/html_node/Very-Simple.html#Very-Simple
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-11 19:01:29
Logika odnosi się do wielu innych celów. A jak odczytać .sh_history każdego użytkownika z /home / filesystem? A jeśli jest ich tysiące?
#!/bin/ksh
last |head -10|awk '{print $1}'|
while IFS= read -r line
do
su - "$line" -c 'tail .sh_history'
done
Oto skrypt https://github.com/imvieira/SysAdmin_DevOps_Scripts/blob/master/get_and_run.sh
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-30 16:41:28