Załóżmy, że mam dane wyjściowe z polecenia (takiego jak ls -1):
a
b
c
d
e
...
Chcę zastosować polecenie (powiedzmy echo) do każdego z nich z kolei. Na przykład
echo a
echo b
echo c
echo d
echo e
...
Jak najłatwiej to zrobić w bash?
Załóżmy, że mam dane wyjściowe z polecenia (takiego jak ls -1):
a
b
c
d
e
...
Chcę zastosować polecenie (powiedzmy echo) do każdego z nich z kolei. Na przykład
echo a
echo b
echo c
echo d
echo e
...
Jak najłatwiej to zrobić w bash?
Odpowiedzi:
Jest to prawdopodobnie najłatwiejszy w użyciu xargs. W Twoim przypadku:
ls -1 | xargs -L1 echo
-LFlaga gwarantuje wejście jest prawidłowo odczytać. Ze strony podręcznika użytkownika xargs:
-L number
Call utility for every number non-empty lines read.
A line ending with a space continues to the next non-empty line. [...]
lsautomatycznie robi to -1w rurze.
ls | xargs -L2 echoi ls -1 | xargs -L2 echodaje dwa różne wyniki. Ten pierwszy jest na jednej linii.
xargsmoże uruchamiać tylko pliki wykonywalne, a nie funkcje powłoki lub wbudowane polecenia powłoki. W przypadku tego pierwszego najlepszym rozwiązaniem jest prawdopodobnie rozwiązanie z readpętlą.
-L1.
Możesz użyć podstawowej operacji poprzedzającej w każdej linii:
ls -1 | while read line ; do echo $line ; done
Lub możesz przesłać dane wyjściowe do sed dla bardziej złożonych operacji:
ls -1 | sed 's/^\(.*\)$/echo \1/'
sh: cho: not found a sh: cho: not foundwygląda na to, że eodbija się echem od polecenia sed lub czegoś takiego.
whilepętlę. cmd1 | while read line; do cmd2 $line; done. Lub while read line; do cmd2 $line; done < <(cmd1)który nie tworzy podpowłoki. To jest uproszczona wersja twojego sedpolecenia:sed 's/.*/echo &/'
"$line"pętlę while, aby uniknąć podziału słów.
read -r lineaby uniknąć readbałaganu ze znakami ucieczki. Na przykład echo '"a \"nested\" quote"' | while read line; do echo "$line"; donedaje "a "nested" quote", który stracił ucieczkę. Jeśli to zrobimy echo '"a \"nested\" quote"' | while read -r line; do echo "$line"; done, otrzymamy "a \"nested\" quote"zgodnie z oczekiwaniami. Zobacz wiki.bash-hackers.org/commands/builtin/read
Możesz użyć pętli for :
dla pliku w *; robić echo „$ file” Gotowe
Zauważ, że jeśli dane polecenie akceptuje wiele argumentów, wówczas użycie xargs jest prawie zawsze bardziej wydajne, ponieważ wystarczy tylko odrodzić dane narzędzie, a nie wiele razy.
printf '%s\0' * | xargs -0 ...- w przeciwnym razie jest to dość niebezpieczne z nazwami plików z białymi spacjami, cytatami itp.
Rzeczywiście można używać sed to zrobić, pod warunkiem, że jest GNU sed.
... | sed 's/match/command \0/e'
Jak to działa:
cat /logs/lfa/Modified.trace.log.20150904.pw | sed -r 's/^(.*)(\|006\|00032\|)(.*)$/echo "\1\2\3 - ID `shuf -i 999-14999 -n 1`"/e'
for s in `cmd`; do echo $s; done
Jeśli cmd ma dużą moc wyjściową:
cmd | xargs -L1 echo
cmdma spacje na wyjściu, pierwsza nie powiedzie się.
xargs kończy się niepowodzeniem z odwrotnymi ukośnikami, cudzysłowami. To musi być coś podobnego
ls -1 |tr \\n \\0 |xargs -0 -iTHIS echo "THIS is a file."
Opcja xargs -0:
-0, --null Input items are terminated by a null character instead of by whitespace, and the quotes and backslash are not special (every character is taken literally). Disables the end of file string, which is treated like any other argument. Useful when input items might contain white space, quote marks, or backslashes. The GNU find -print0 option produces input suitable for this mode.
ls -1kończy elementy znakami nowej linii, więc trtłumaczy je na znaki puste.
To podejście jest około 50 razy wolniejsze niż iteracja ręczna for ...(patrz odpowiedź Michaela Aarona Safyana ) (3,55s vs. 0,066s). Ale w przypadku innych poleceń wejściowych, takich jak lokalizuj, znajdź, odczytuj z pliku ( tr \\n \\0 <file) lub podobnego, musisz pracować w xargsten sposób.
Lepszy wynik dla mnie:
ls -1 | xargs -L1 -d "\n" CMD
find . -mindepth 1 -maxdepth 1 -print0 | xargs -0 commandzajmie się przypadkami, w których wynik ls -1jest niejednoznaczny; używaj -printf '%P\0'raczej, niż -print0jeśli nie chcesz prowadzić ./na każdym z nich.
ls -1może być tutaj przykładem, ale ważne jest, aby pamiętać, że analizowanie wyniku nie jest dobrels. Zobacz: mywiki.wooledge.org/ParsingLs