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?
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:
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 read
dö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 IFS
sadece 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.
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 )
cat
con cat enates dosyaları. Ayrıca içeriklerini yazdırır.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 tee
birlikte -a
- bu dosya zaten var durumda anahtarı ekler zaten varsa, üzerine yazmak yerine dosyaya)
cat
tüm listeyi tek bir argüman olarak alır.
GNU awk
bir 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
"$(cat list_of_files.txt)"