Bir listedeki her dosyanın içeriğini başka bir dosyaya nasıl kopyalarım?


15

Adlı bir dosyanın içindeki dosya adlarının bir listesi var list_of_files.txt.

Bu listedeki her dosyanın içeriğini adlı başka bir dosyaya kopyalamak istiyorum all_compounds.sdf.

Bunu komut satırından nasıl yapmalıyım?

Yanıtlar:


20

Dosya adlarını almak için basit komut ikamesi kullanmayın (boşluklarla ve diğer özel karakterlerle kolayca bozulabilir). Şunun gibi bir şey kullanın xargs:

xargs -d '\n' -a list_of_files.txt cat > all_compounds.sdf

Veya bir while readdöngü:

while IFS= read -r file; do cat "$file"; done < list_of_files.txt > all_compounds.sdf

Komut ikamesini güvenli bir şekilde kullanmak için, en azından IFSsadece yeni satıra ayarlayın ve globbing'i devre dışı bırakın (joker karakter genişletme):

(set -f; IFS=$'\n'; cat $(cat list_of_files.txt) > all_compounds.sdf)

Çevredeki parantezler ()bunu bir alt kabukta çalıştırır, böylece mevcut kabuğunuz bu değişikliklerden etkilenmez.


14

Hızlı ve kirli bir yol ...

cat $(cat list_of_files.txt) >> all_compounds.sdf

Lütfen dikkat: bu yalnızca listenizdeki dosya adları çok iyi davrandıysa işe yarar - boşluklar, yeni satırlar veya kabuğa özel bir anlamı olan karakterler varsa işler ters gidecektir - güvenilir sonuçlar için bu cevabı kullanın )

notlar

  • catcon cat enates dosyaları. Ayrıca içeriklerini yazdırır.
  • Komut ikamesi kullanarak command2 $(command1)size çıktısını geçebilir command1( cat list...kadar) command2( cat) dosyalarını birleştirir hangi.
  • Ardından >>çıktıyı stdout'a yazdırmak yerine bir dosyaya göndermek için yeniden yönlendirmeyi kullanın. Çıktıyı görmek istiyorsanız, şunu kullanın tee:

    cat $(cat list_of_files.txt) | tee -a all_compounds.sdf

(Ben kullandım >>yerine >ve teebirlikte -a- bu dosya zaten var durumda anahtarı ekler zaten varsa, üzerine yazmak yerine dosyaya)


1
@Zanna gibi kelime bölme önlemek için komut ikameleri, gibi"$(cat list_of_files.txt)"
Sergiy Kolodyazhnyy

4
@ Sözcük bölme yapılmazsa, cattüm listeyi tek bir argüman olarak alır.
muru

@muru Tamam, o zaman boşluk içeren dosya adlarıyla nasıl başa çıkacağız?
Sergiy Kolodyazhnyy

1
@Serg IFS'i buna göre ayarladı
cevabımın

4

GNU awkbir metin işleme yardımcı programı olsa da, dış kabuk komutlarını system()çağrı yoluyla çalıştırmaya izin verir . Bunu kendi yararımıza şöyle kullanabiliriz:

$ awk '{cmd=sprintf("cat \"%s\"",$0); system(cmd)}' file_list.txt                                                        

Buradaki fikir basit: dosyayı satır satır okuyoruz ve her satırdan biçimlendirilmiş dize oluşturuyoruz cat "File name.txt", bu daha sonra aktarılıyor system().

Ve işte burada:

$ ls
file1.txt  file2.txt  file3 with space.txt  file_list.txt


$ awk '{cmd=sprintf("cat \"%s\"",$0); system(cmd)}' file_list.txt                                                        
Hi, I'm file2
Hi, I'm file1
Hi, I'm file3

Buradaki görevin büyük bölümünü zaten yaptık - listedeki tüm dosyaları yazdırdık. Gerisi basit: son çıktıyı >işleç ile özet dosyasına dosyaya yönlendirin.

awk '{cmd=sprintf("cat \"%s\"",$0); system(cmd)}' file_list.txt > output.txt
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.