İki çift tırnak arasında sed get substring kullanma


14

Bir dosyam var

xyz... rsync: "/home/path/to/file": Permission denied (13) rsync:
"/home/path/to/file1": Permission denied (13) rsync:
"/home/path/to/file2": Permission denied (13) rsync:
"/home/path/to/file3": Permission denied (13)

Şimdi sadece dosya yollarını ayıklamak ve başka bir dosyaya saklamak istiyorum. Çıktı dosyası şöyle:

/home/path/to/file 
/home/path/to/file1 
/home/path/to/file2
/home/path/to/file3

Sed veya awk kullanarak bunu nasıl yapabilirim?

Denedim sed -n '/"/,/"/p' myfileama çalışmıyor.


3
Kapatmak için oy kullananlara - Bu nasıl konu dışı olabilir? Kabuk programlama ile ilgili !! Yığın Taşması için BAŞLIKTA PROGRAMLAMA işte bu!
Jonathan Leffler

2
Stack Overflow'a hoş geldiniz. Gördüğünüz gibi, kaşıntılı tetik parmaklarının kapanması için kötü nedenlerle (bu gibi) mükemmel iyi soruları kapatmasıyla ilgili sorunlar yaşıyoruz. Bu kadar sık ​​olmaz (ya da problemi zamanında çok sık göremiyorum), ama olur. Çok uzun süre önce SSS bölümünü okumayı unutmayın .
Jonathan Leffler

Yanıtlar:


17

Rsync komutunuzun stderr'ını bir awk komut dosyasına aktarabilirsiniz:

awk -F '"' '{print $2}' 

Veya böyle bir kesme komutuna:

cut -d'"' -f2

2
Veya daha kısa:cut -d\" -f2

@AndersJohansson: Teşekkürler ben de cevaplamak için kesme komutunu ekledim.
anubhava

Sanırım bu işe yaramayacak .. dosya yolunun alan sayısı 2 $ veya f2 sabit değil görebilirsiniz gibi .. Teşekkürler!

Aslında rsync her zaman önce stderr arasında "ve "üzerinde dosyayolu yazar.
anubhava

1
@ Jam88: Aslında, anubbhava'nın yazdığı şekilde çalışacak. Alan sınırlayıcı, çift tırnak olarak ayarlanmıştır. Bu, ilk çift tırnak (muhtemelen boş bir dize) kadar olan her şeyin $1; birinci ve ikinci çift tırnak arasındaki her şey $2; ve ikinci çift tırnaktan sonraki her şey $3( $4, ...) içinde. Dosya adı (görünüşte) her zaman ilk iki çift tırnak arasındadır, bu nedenle bu çözüm çalışmalıdır (ve test ettiğimde).
Jonathan Leffler

6

Kullanma sed:

sed 's/^[^"]*"\([^"]*\)".*/\1/'

Şuna benzer: satır başı, bir dizi tırnaksız, bir çift tırnak, bir dizi tırnaksız, bir çift tırnak ve hatta başka bir şey yakalar ve yakalanan malzeme ile değiştirir.

$ sed 's/^[^"]*"\([^"]*\)".*/\1/' <<'EOF'
> xyz... rsync: "/home/path/to/file": Permission denied (13) rsync:
> "/home/path/to/file1": Permission denied (13) rsync:
> "/home/path/to/file2": Permission denied (13) rsync:
> "/home/path/to/file3": Permission denied (13)
> EOF
/home/path/to/file
/home/path/to/file1
/home/path/to/file2
/home/path/to/file3
$

GNU ile RHEL 5 Linux üzerinde test edin sed, ancak yalnızca 7. Sürüm UNIX ™ sürümünde çalışacak özellikleri kullanın sed.

Bu arada, bunu yapmanın biraz daha basit bir yolu iki yedek komuttur; ilk çift tırnak işaretini boş bir dizeye (bu sıfır veya daha fazla tırnak işareti ve ardından çift tırnak işareti) içeren her şeyi değiştirin; şimdi ilk çift alıntı olan şeyden sonra her şeyi değiştirin:

sed 's/^[^"]*"//; s/".*//'

Bu arada, denediğiniz komut (`sed -n '/" /, / "/ p'), çift tırnak içeren bir satırdan, çift tırnak içeren bir sonraki satıra, satırları düzenlemeden yazdırır. Bu yüzden sizin için işe yaramıyordu - sorduğunuz şeyi yaptı, ancak yapmasını istediğiniz şey, yapmasını istemediğiniz şey değildi.

Verimlilik açısından, performansta ölçülebilir bir fark olması olası değildir. Bakım kolaylığı açısından, ikincisinin beyin hücrelerine daha az vergi yüklediğinden şüpheleniyorum.


1

Sürümünüz grepPerl-regexp'yi destekliyorsa:

grep -oP '(?<=")/home/.*?(?=")' file >> anotherfile

Sonuçlar:

/home/path/to/file
/home/path/to/file1
/home/path/to/file2
/home/path/to/file3

İsterseniz çiftler arasındaki herhangi bir şeyi eşleştirmek için bunu daha az katı hale getirebilirsiniz:

grep -oP '(?<=")[^"]*' file >> anotherfile

Daha sonra satırda fazladan bir çift alıntı olması durumunda .*açgözlü olmayanı yapmanız gerekiyor .*?mu? Veya kullanmak [^"]*yerine .*?
Jonathan Leffler

-1

Herhangi bir çıktıyı bir dosyaya kaydetmek için >> işlecini kullanın.

Sevmek

grep -r "pattern" * >> file.txt

Yani sadece sed kullanarak özel senaryo için bunu değiştirin

>> filename

komuta


grep -rArgüman olarak belirtilenler herhangi dizinleri (aracılığıyla bir özyinelemeli arama yapar *). Aklınızda hangi desenin olduğu açık değil, ancak greptüm çizgiyi alacak. Alıştırmanın amacı bir hattın bir kısmından bilgi toplamaktır. GNU kullanıyorsanız grep, bunu yapmanın yolları vardır ( -o); bunlar standart değildir (GNU'nun fiili bir standart tanımladığı durumlar hariç). PCRE düzenli ifadelerinin kullanımı ile benzer şekilde; bunlar başka bir GNU uzantısıdır. GNU'nuz varsa grepve GNU'nun grepvarsayılan olarak kullanılamadığı platformlarda çalışma planı yoksa sorun yoktur .
Jonathan Leffler

Üzgünüm bunu özledim, genel olarak bir dosyaya çıktı koymak için ne yapacağını bilmek istediğini düşündüm ve grep sadece bir örnekti.
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.