Bir komuttan (örneğin ls -1) bazı çıktılar aldığımı varsayalım :
a
b
c
d
e
...
echoSırayla her birine bir komut uygulamak istiyorum . Örneğin
echo a
echo b
echo c
echo d
echo e
...
Bunu bash'da yapmanın en kolay yolu nedir?
Bir komuttan (örneğin ls -1) bazı çıktılar aldığımı varsayalım :
a
b
c
d
e
...
echoSırayla her birine bir komut uygulamak istiyorum . Örneğin
echo a
echo b
echo c
echo d
echo e
...
Bunu bash'da yapmanın en kolay yolu nedir?
Yanıtlar:
Muhtemelen kullanımı en kolay olanıdır xargs. Senin durumunda:
ls -1 | xargs -L1 echo
-LBayrak girişi düzgün okunur sağlar. Man sayfasından 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. [...]
lsotomatik olarak -1bir boruda yapar.
ls | xargs -L2 echove ls -1 | xargs -L2 echoiki farklı çıktı veriyor. İlki tek bir hatta.
xargskabuk işlevlerini veya kabuk yerleşik komutlarını değil, yalnızca yürütülebilir dosyaları çalıştırabilir. Birincisi için en iyi çözüm muhtemelen readbir döngüde olan çözümdür .
-L1için bir açıklama içermesini isterdim .
Her satırda temel bir başa ekleme işlemi kullanabilirsiniz:
ls -1 | while read line ; do echo $line ; done
Veya daha karmaşık işlemler için çıkışı boru hattına bağlayabilirsiniz:
ls -1 | sed 's/^\(.*\)$/echo \1/'
sh: cho: not found a sh: cho: not foundGörünüşe egöre bir sed komutu falan için yankı alıyor .
whileDöngü için +1 . cmd1 | while read line; do cmd2 $line; done. Ya while read line; do cmd2 $line; done < <(cmd1)da alt kabuk oluşturmayan. Bu, sedkomutunuzun basitleştirilmiş sürümüdür :sed 's/.*/echo &/'
"$line"Sözcük bölünmesini önlemek için while döngüsünde alıntı yapın .
read -r lineönlemek için kullanmayı deneyin read. Örneğin , kaçışını kaybetmiş echo '"a \"nested\" quote"' | while read line; do echo "$line"; doneverir "a "nested" quote". Eğer yaparsak beklediğimiz gibi echo '"a \"nested\" quote"' | while read -r line; do echo "$line"; donealırız "a \"nested\" quote". Bkz. Wiki.bash-hackers.org/commands/builtin/read
For döngüsü kullanabilirsiniz :
* içindeki dosya için; yapmak echo "$ file" tamam
Söz konusu komut birden fazla bağımsız değişkeni kabul ederse, xargs kullanmanın , söz konusu yardımcı programı birden çok kez yerine yalnızca bir kez oluşturması gerektiğinden neredeyse her zaman daha verimli olduğunu unutmayın.
printf '%s\0' * | xargs -0 ...- Aksi takdirde, boşluk, tırnak işareti vb. içeren dosya adlarıyla oldukça güvensizdir
Aslında olabilir , bunu yapmak için sed GNU sed koşuluyla kullanın.
... | sed 's/match/command \0/e'
Nasıl çalışır:
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
Cmd'nin büyük bir çıkışı varsa:
cmd | xargs -L1 echo
cmdçıktısında boşluklar varsa , ilki başarısız olur.
xargs ters eğik çizgi, tırnak işareti ile başarısız olur. Bunun gibi bir şey olmalı
ls -1 |tr \\n \\0 |xargs -0 -iTHIS echo "THIS is a file."
xargs -0 seçeneği:
-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 -1yeni satır karakterleri olan öğeleri sonlandırır, bu nedenle tronları boş karakterlere dönüştürür.
Bu yaklaşım, manuel olarak yinelemekten yaklaşık 50 kat daha yavaştır for ...(bkz. Michael Aaron Safyan'ın cevabı) (3.55s ve 0.066s). Ancak locate, find, bir dosyadan ( tr \\n \\0 <file) veya benzeri bir şeyden okuma gibi diğer giriş komutları için bununla çalışmanız gerekir xargs.
Benim için daha iyi sonuç:
ls -1 | xargs -L1 -d "\n" CMD
find . -mindepth 1 -maxdepth 1 -print0 | xargs -0 commandçıktısının ls -1belirsiz olduğu durumları ele alacaktır ; her biri için bir lider istemiyorsanız -printf '%P\0'yerine kullanın . -print0./
ls -1burada bir örnek olabilir, ancak çıktısını ayrıştırmanın iyi olmadığını hatırlamak önemlidirls. Bkz: mywiki.wooledge.org/ParsingLs