Yol eğik çizgisinden sonra bastırma ayracı genişlemesi


12

Brace genişletme kullanarak aynı dizine farklı bir ada bir dosya kopyalamaya çalışıyorum. 4.4.18 bash kullanıyorum.

İşte yaptım:

cp ~/some/dir/{my-file-to-rename.bin, new-name-of-file.bin}

ama bu hatayı alıyorum:

cp: cannot stat '/home/xyz/some/dir/{my-file-to-rename.bin,': No such file or directory

Bunun gibi basit bir destek genişletmesi bile bana aynı hatayı veriyor:

cp {my-file-to-rename.bin, new-name-of-file.bin}

Neyi yanlış yapıyorum?

Yanıtlar:


29

Ayracı genişleme sözdizimi virgül kabul eder; ancak virgülden sonra boşluk kabul etmez. Birçok programlama dilinde, virgüllerden sonraki boşluklar yaygındır, ancak burada değildir. Bash'te alıntılanmamış bir alanın bulunması, küme ayracı genişlemesinin yapılmasını önler.

Alanı kaldırın, işe yarayacak:

cp ~/some/dir/{my-file-to-rename.bin,new-name-of-file.bin}

Gerekli olmasa da, sondaki .binparantezleri parantezlerin dışına taşıyabileceğinizi unutmayın :

cp ~/some/dir/{my-file-to-rename,new-name-of-file}.bin

Eğer ayracı genişleme etkisini test etmek istiyorsanız, kullanabileceğiniz echoveya printf '%s 'veya printfbunu yapmak için, ne olursa olsun tercih biçim dizesi ile. (Şahsen ben sadece Bash'deyken bunun echoiçin kullanıyorum , çünkü Bash'ın echoyerleşimi varsayılan olarak kaçış dizilerini genişletmez ve bu nedenle hangi komutun gerçekten çalışacağını kontrol etmek için oldukça uygundur.) Örneğin:

ek@Io:~$ echo cp ~/some/dir/{my-file-to-rename,new-name-of-file}.bin
cp /home/ek/some/dir/my-file-to-rename.bin /home/ek/some/dir/new-name-of-file.bin

23

string{foo, bar}destek genişletme değildir; bu iki kelime string{foo,ve bar}. Küme ayracı genişletmeyi kullanmak için, parantezlerin aynı sözcük içinde olması gerekir. İhtiyacınız yoksa ekstra alanı kaldırmanız veya ihtiyacınız varsa alıntı yapmanız gerekir:

$ printf "%s\n" aa{bb, cc}
aa{bb,
cc}
$ printf "%s\n" aa{bb,cc}
aabb
aacc
$ printf "%s\n" aa{bb," cc"}
aabb
aa cc

Net örnek için +1 ve teşekkür ederim. İtibarım yeterli olduğunda oyumu vereceğim. :)
nanangarsyad

"Kabuk sözleri" hakkında bahsedilmesi gereken başka bir şey daha var. . Kabuk, kelimeleri nerede
Sergiy Kolodyazhnyy

-1

Bash bu alana diğer her şey gibi davranır. IFS olarak, Dahili Alan Ayırıcı. Bu, genişletmeden sonra sözcük bölme ve read builtin komutuyla satırları kelimelere bölmek için kullanılır.

Kabuk, IFS'nin her karakterine bir sınırlayıcı olarak davranır ve diğer genişletmelerin sonuçlarını bu karakterler üzerindeki kelimelere böler. IFS ayarlanmamışsa veya değeri tam olarak varsa, önceki genişletmelerin sonuçlarının varsayılan,, ve başında ve sonunda sıraları yok sayılır ve başında veya sonunda olmayan herhangi bir IFS karakteri dizisi sınırlandırılır kelimeler. IFS varsayılan dışında bir değere sahipse, boşluk karakteri IFS (IFS boşluk karakteri) değerinde olduğu sürece, boşluk karakterleri boşluk ve sekme dizileri sözcüğün başında ve sonunda yok sayılır. IFS'de IFS boşluk olmayan herhangi bir karakter, bitişik IFS boşluk karakterleriyle birlikte bir alanı sınırlar. Bir dizi IFS boşluk karakteri de sınırlayıcı olarak ele alınır. IFS değeri null ise,
-bash (1)

Sınırsız, çıkışsız ekleyerek bash komutunuzu ve bağımsız değişkenlerini şöyle söylediniz:

  1. "Cp"
  2. "~ / Some / dir / {my-dosya-to-rename.bin,"
  3. "Yeni-name-of-file.bin}"

Eğer tırnak veya kaçış "\" olsaydı, olurdu:

  1. "Cp"
  2. "~ / some / dir / {yeniden adlandırılacak dosyam.bin, \ new-name-of-file.bin}"

"New-name-of-file.bin" istediğiniz yeni dosya adı olmadıkça bu da istediğiniz gibi olmaz. Alan dahil. İlk olarak küme ayracı genişlemesi ve daha sonra tilde genişleme gerçekleştiğinde, bash yürütür:

  1. "Cp"
  2. "/Path/to/home/some/dir/my-file-to-rename.bin"
  3. "/ path / to / home / some / dir / \ new-of-file.bin"

Sadece alanı kaldırmak tüm bunları düzeltir.


5
Bu çoğunlukla iyidir, ancak kelime bölmenin gerçekleştiğini cp ~/some/dir/{my-file-to-rename.bin, new-name-of-file.bin}ve IFSsonucu etkilediğini söylüyorsunuz . İkisi de öyle değil. Burada mekan, tokenizasyonda bir metakarakterdir ( adım 2 ). Bölme işleminin ne zaman yapılacağı konusunda 3.5.7'ye bakın . IFS=xO zaman dene printf '[%s]\n' {a,b} printf '[%s]\n' {a, b} printf '[%s]\n' {a,xb} printf '[%s]\n' {a, xb}.
Eliah Kagan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.