Dlaczego xargs usuwa cytaty z danych wejściowych?


25

Dlaczego xargs usuwa cudzysłowy z tekstu wejściowego?

Oto uproszczony przykład:

echo "/Place/='http://www.google.com'" | xargs echo

wyjścia

/Place/=http://www.google.com

Czy jest jakiś sposób na obejście tego? (xargs -0 mi nie pomaga)


1
xargstraktuje cytaty i odwrotne ukośniki specjalnie jako część specyfikacji . xargsZamiast tego opublikuj to, co próbujesz zrobić .
jw013

3
xargs -0działa tutaj dla mnie ... Dlaczego to nie pomaga?
derobert

Odpowiedzi:


10

Z xargsinstrukcji:

Jeśli chcesz, aby argument wejściowy zawierał spacje lub tabulacje poziome, umieść go w cudzysłowach lub apostrofach. Jeśli argument zawiera znak podwójnego cudzysłowu ( "), musisz umieścić argument w apostrofach. I odwrotnie, jeśli argument zawiera apostrof ( '), należy umieścić argument w podwójnych cudzysłowach. Możesz także umieścić odwrotny ukośnik ( \) przed znakiem, aby xargs zignorował jakiekolwiek specjalne znaczenie, jakie może mieć znak (na przykład białe znaki lub cudzysłowy).

Oznacza to, że możesz uciec od cytatów, jeśli cytaty są cytowane same:

$ echo "/Place/=\'http://www.google.com\'" | xargs echo
/Place/='http://www.google.com'

będzie działać, ale echo /Place/=\'http://www.google.com\' | xargs echonie będzie.


1
Nie pomogłoby nic przeciw głosom negatywnym, ale komentarz na temat przyczyny :-)
Matteo,

3
Co jeśli przesyłasz dane wejściowe? Jeśli mam skrypt, który wyświetla dane wyjściowe "/Place/='http://www.google.com'", w jaki sposób mogę go właściwie uciec?
Roger Filmyer

1
@RogerFilmyer your_script | równoległy --shellquote | ...
Ole Tange 18.04.16

19

jeśli chcesz xargs, aby zignorować cytuje jeden z dobrych soultion może być użycie xargsflagi xargs -0

Bezpośrednio ze strony Man OPCJE

OPCJE -0, - zero

Elementy wejściowe są zakończone znakiem null zamiast spacją, a cudzysłowy i odwrotne ukośniki nie są wyjątkowe (każdy znak jest traktowany dosłownie). Wyłącza koniec ciągu pliku, który jest traktowany jak każdy inny argument. Przydatne, gdy elementy wejściowe mogą zawierać spacje, znaki cudzysłowu lub ukośniki odwrotne. Opcja GNU find -print0 tworzy dane wejściowe odpowiednie dla tego trybu.

Sprawdziłem w systemie GNU, że ustawienie ogranicznika na określoną wartość (jak nowy wiersz) z -dopcją (i nie tylko -0) spowoduje, że xargsnie będzie traktować cudzysłowów itp. Specjalnie:

-bash-4.3$ { echo "a'b'c"; echo d; } | xargs -d$'\n' echo
a'b'c d
-bash-4.3$ rpm -qf "$(which xargs)"
findutils-4.6.0.0.99.11a05-alt1.x86_64
-bash-4.3$ { echo "a'b'c"; echo d; } | xargs echo
abc d
-bash-4.3$ 


7

Znalazłem inne rozwiązanie na stronie podręcznika: jawnie określ separator jako „\ n”. Wyłącza to specjalną obsługę cytatów:

--delimiter = delim, -d delim

Elementy wejściowe są zakończone określonym znakiem. Określony separator może być pojedynczym znakiem, znakiem ucieczki w stylu C, takim jak \ n, lub ósemkowym lub szesnastkowym kodem ucieczki. Ośmio i szesnastkowe kody ucieczki są rozumiane jak dla polecenia printf. Znaki wielobajtowe nie są obsługiwane. Podczas przetwarzania danych wejściowych cudzysłowy i ukośnik odwrotny nie są wyjątkowe; każdy znak na wejściu jest traktowany dosłownie.

Więc,

echo "/Place/='http://www.google.com'" | xargs -d'\n' echo

wyjścia

/Place/='http://www.google.com'

Zauważ, że implikuje GNU xargslub kompatybilny
Stéphane Chazelas,

Zauważ też, że zapobiega to rozpoznawaniu spacji i tabulacji jako ograniczników (prawdopodobnie równie dobrze w przypadku PO).
Stéphane Chazelas,

Balman podał podobne rozwiązanie ( właściwie @imz ), chociaż twoje jest nieco lepsze, ponieważ pozwala uniknąć użycia ksh93 $'...'operatora cytowania, którego nie ma w każdej implementacji powłoki.
Stéphane Chazelas,

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.