Mengapa xarg mengutip tanda kutip dari input?

25

Mengapa xarg mengutip tanda kutip dari teks input?

Ini adalah contoh sederhana:

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

output

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

Apakah ada cara untuk mengatasi ini? (xargs -0 tidak membantu saya)

ddario
sumber
1
xargsmemperlakukan penawaran dan garis miring terbalik khusus sebagai bagian dari spesifikasi . Poskan apa yang ingin Anda lakukan xargs.
jw013
3
xargs -0bekerja untuk saya di sini ... Mengapa itu tidak membantu Anda?
derobert

Jawaban:

10

Dari xargsmanual:

Jika Anda ingin argumen input mengandung kosong atau tab horisontal, lampirkan dalam tanda kutip ganda atau apostrof. Jika argumen berisi karakter kutipan ganda ( "), Anda harus melampirkan argumen dalam apostrof. Sebaliknya, jika argumen berisi tanda kutip ( '), Anda harus menyertakan argumen dalam tanda kutip ganda. Anda juga dapat meletakkan garis miring terbalik ( \) di depan karakter untuk memberi tahu xargs untuk mengabaikan makna khusus apa pun yang mungkin dimiliki karakter tersebut (misalnya, karakter spasi, atau kutipan).

Ini berarti Anda dapat menghindari tanda kutip jika tanda kutip dikutip sendiri:

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

akan bekerja tetapi echo /Place/=\'http://www.google.com\' | xargs echotidak akan.

Matteo
sumber
1
Tidak ada yang menentang suara tetapi komentar pada alasan akan membantu :-)
Matteo
3
Bagaimana jika Anda memasukkan input? Jika saya memiliki skrip yang menghasilkan "/Place/='http://www.google.com'", bagaimana saya bisa menghindarinya?
Roger Filmyer
1
@RogerFilmyer your_script | parallel --shellquote | ...
Ole Tange
19

jika Anda ingin xargsuntuk mengabaikan tanda kutip salah satu soultion baik dapat penggunaan xargsbendera xargs -0

Langsung dari halaman manual OPSI

OPSI -0, --null

Item input diakhiri oleh karakter nol alih-alih oleh spasi, dan tanda kutip dan garis miring terbalik tidak khusus (setiap karakter diambil secara harfiah). Menonaktifkan akhir string file, yang diperlakukan seperti argumen lain. Berguna saat item input mungkin mengandung spasi, tanda kutip, atau garis miring terbalik. Opsi GNU find -print0 menghasilkan input yang cocok untuk mode ini.

Saya telah memeriksa sistem GNU yang mengatur pembatas ke nilai tertentu (seperti baris baru) dengan -dopsi (dan bukan hanya -0) juga akan menyebabkan xargstidak memperlakukan tanda kutip dll khusus:

-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$ 
Balman Rawat
sumber
7

Saya menemukan solusi lain di halaman manual: tentukan secara spesifik pembatas sebagai '\ n'. Ini mematikan penanganan khusus untuk kutipan:

--delimiter = delim, -d delim

Item input diakhiri oleh karakter yang ditentukan. Pembatas yang ditentukan dapat berupa karakter tunggal, karakter pelolosan gaya-C seperti \ n, atau kode escape oktal atau heksadesimal. Kode melarikan diri oktal dan heksadesimal dipahami seperti untuk perintah printf. Karakter multibyte tidak didukung. Saat memproses input, tanda kutip dan garis miring terbalik tidak khusus; setiap karakter dalam input diambil secara harfiah.

Begitu,

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

output

/Place/='http://www.google.com'
jamurung
sumber
Perhatikan bahwa ini menyiratkan GNU xargsatau yang kompatibel
Stéphane Chazelas
Juga perhatikan bahwa itu juga menghentikan ruang dan tab agar tidak dikenali sebagai pembatas (mungkin juga dalam kasus OP).
Stéphane Chazelas
Balman memberikan solusi yang serupa ( sebenarnya @imz ) meskipun milik Anda agak lebih baik karena ia menghindari penggunaan ksh93 $'...'operator mengutip yang tidak ditemukan dalam setiap implementasi shell.
Stéphane Chazelas
4

Saya menemukan solusi lain di sini /programming//a/17468560/1795821 yang menyarankan penggunaan seduntuk menghindari kutip.

Sebagai contoh:

sh-3.2$ echo "/Place/='http://www.google.com'" | sed "s/\'/\\\'/g" | xargs echo
/Place/='http://www.google.com'
Kristofor Carle
sumber