Przekieruj do stdin zamiast argumentu, gdy używasz xargs [zamknięte]

12

dla exmaple za pomocą polecenia

cat foo.txt | xargs -I{} -n 1 -P 1 sh -c "echo {} | echo"

foo.txtZawiera dwie linie

foo
bar

Powyższe polecenie nic nie drukuje.

Ryan
źródło

Odpowiedzi:

6
cat foo.txt | xargs -J % -n 1 sh -c "echo % | bar.sh" 

Chodzi o to, że xargs wykonuje niejawne wywołanie podpowłoki. Wywołano tutaj jawnie, a rura nie staje się częścią przenośnika macierzystego

Kondybas
źródło
1
Dzięki, zaktualizowałem moje pytanie, aby podać bardziej konkretny przykład. ale to nie działa tak, jak sugerowałeś ...
Ryan
1
echo nie może odczytać ze standardowego wejścia, więc przesyłanie do niego nie ma sensu. porównaj to: cat foo.bar | wc -licat foo.bar | xargs -J % -n 1 sh -c "echo % | wc -l"
Kondybas
1
Myślę, że masz na myśli -Izamiast -J; -Jxargs nie ma opcji
Hitechcomputergeek
@Hitechcomputergeek Wersja FreeBSD xargsma -Jopcję, która jest odpowiednikiem -ilinuksaxargs
Kondybas
@Kondybas Dzięki, że mi to powiedziałeś; Nie wiedziałem, że między nimi jest różnica. Możesz zaufać GNU, że nie będzie postępować zgodnie z POSIX lol. ( -Jnie jest zdefiniowany w POSIX, ale -Ijest i ma inne zastosowanie niż GNU.)
Hitechcomputergeek
2

Jeśli chcesz przetworzyć wszystkie linie foo.txt, będziesz musiał użyć pętli. Użyj, &aby umieścić proces w tle

while read line; do
   echo $line | bar.sh &
done < foo.txt

Jeśli dane wejściowe zawierają spacje, tymczasowo ustaw wewnętrzny separator pól na nowy wiersz

# save the field separator
OLD_IFS=$IFS

# new field separator, the end of line 
IFS=$'\n'

for line in $(cat foo.txt) ; do
   echo $line | bar.sh &
done

# restore default field separator  
IFS=$OLD_IFS     
Matteo
źródło
Nie, nie, ja też utknąłem. TS chce podzielić plik na osobne linie i wprowadzić je osobno do skryptu
Kondybas
1
Muszę użyć xargs do równoległego procesu.
Ryan
OK :-) Właśnie sprawdziłem opcje xargsużytego OP.
Matteo,