@Dennis, nie wygląda to tak: ls | xargs -L2 echoi ls -1 | xargs -L2 echodaje dwa różne wyniki. Ten pierwszy jest na jednej linii.
Alex Budovski,
2
@Alex: Dostaję to samo wyjście.
Wstrzymano do odwołania.
6
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ą.
pabouk
12
Chciałbym, aby ta odpowiedź zawierała wyjaśnienie, po co -L1.
Wyck
164
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:
Wydaje się, że polecenie sed nie działa: sh: cho: not found a sh: cho: not foundwygląda na to, że eodbija się echem od polecenia sed lub czegoś takiego.
Alex Budovski
+1 za 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 &/'
Wstrzymana do odwołania.
1
@Alex: zmień podwójne cudzysłowy na pojedyncze.
Wstrzymano do odwołania.
5
Cytuj "$line"pętlę while, aby uniknąć podziału słów.
ignis,
3
Spróbuj użyć, 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
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.
Warto opisać prawidłowe / bezpieczne korzystanie z xargs, tj. printf '%s\0' * | xargs -0 ...- w przeciwnym razie jest to dość niebezpieczne z nazwami plików z białymi spacjami, cytatami itp.
Charles Duffy
8
Rzeczywiście można używać sed to zrobić, pod warunkiem, że jest GNU sed.
Fantastyczny. Zapomniałem umieścić polecenie e na końcu, ale zrobiłem to po zobaczeniu twojej odpowiedzi i zadziałało. Próbowałem dołączyć losowy identyfikator między 1000 a 15000, gdy SED pasuje do linii. 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'
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.
Lepsze, ale nie idealne. 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.
Charles Duffy
1
na przykład lubię używać gawk do uruchamiania wielu poleceń na liście
ls -l | gawk '{system("/path/to/cmd.sh "$1)}'
jednak ucieczka uciekających postaci może być nieco owłosiona.
ls -1
może być tutaj przykładem, ale ważne jest, aby pamiętać, że analizowanie wyniku nie jest dobrels
. Zobacz: mywiki.wooledge.org/ParsingLsOdpowiedzi:
Jest to prawdopodobnie najłatwiejszy w użyciu
xargs
. W Twoim przypadku:-L
Flaga gwarantuje wejście jest prawidłowo odczytać. Ze strony podręcznika użytkownikaxargs
:źródło
ls
automatycznie robi to-1
w rurze.ls | xargs -L2 echo
ils -1 | xargs -L2 echo
daje dwa różne wyniki. Ten pierwszy jest na jednej linii.xargs
moż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 zread
pętlą.-L1
.Możesz użyć podstawowej operacji poprzedzającej w każdej linii:
Lub możesz przesłać dane wyjściowe do sed dla bardziej złożonych operacji:
źródło
sh: cho: not found a sh: cho: not found
wygląda na to, żee
odbija się echem od polecenia sed lub czegoś takiego.while
pętlę.cmd1 | while read line; do cmd2 $line; done
. Lubwhile read line; do cmd2 $line; done < <(cmd1)
który nie tworzy podpowłoki. To jest uproszczona wersja twojegosed
polecenia:sed 's/.*/echo &/'
"$line"
pętlę while, aby uniknąć podziału słów.read -r line
aby uniknąćread
bałaganu ze znakami ucieczki. Na przykładecho '"a \"nested\" quote"' | while read line; do echo "$line"; done
daje"a "nested" quote"
, który stracił ucieczkę. Jeśli to zrobimyecho '"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/readMożesz użyć pętli for :
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.
źródło
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.
Jak to działa:
źródło
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'
Jeśli cmd ma dużą moc wyjściową:
źródło
cmd
ma spacje na wyjściu, pierwsza nie powiedzie się.xargs kończy się niepowodzeniem z odwrotnymi ukośnikami, cudzysłowami. To musi być coś podobnego
Opcja xargs -0:
ls -1
kończy elementy znakami nowej linii, więctr
tł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ć wxargs
ten sposób.źródło
Lepszy wynik dla mnie:
źródło
find . -mindepth 1 -maxdepth 1 -print0 | xargs -0 command
zajmie się przypadkami, w których wynikls -1
jest niejednoznaczny; używaj-printf '%P\0'
raczej, niż-print0
jeśli nie chcesz prowadzić./
na każdym z nich.na przykład lubię używać gawk do uruchamiania wielu poleceń na liście
jednak ucieczka uciekających postaci może być nieco owłosiona.
źródło