Bagaimana cara menyalin konten setiap file dalam daftar ke file lain?


15

Saya memiliki daftar nama file di dalam file yang disebut list_of_files.txt.

Saya ingin menyalin konten setiap file dalam daftar itu ke file lain yang disebut all_compounds.sdf.

Bagaimana saya harus melakukan ini dari baris perintah?

Jawaban:


20

Jangan gunakan substitusi perintah sederhana untuk mendapatkan nama file (yang dapat dengan mudah dipecah dengan spasi dan karakter khusus lainnya). Gunakan sesuatu seperti xargs:

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

Atau satu while readlingkaran:

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

Untuk menggunakan penggantian perintah dengan aman, setidaknya setel IFSke baris baru dan nonaktifkan globbing (ekspansi wildcard):

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

Tanda kurung di sekitarnya ()menjalankan ini dalam subkulit, sehingga shell Anda saat ini tidak terpengaruh oleh perubahan ini.


14

Cara cepat dan kotor ...

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

Harap dicatat: ini hanya berfungsi jika nama file dalam daftar Anda berperilaku sangat baik - ada yang salah jika mereka memiliki spasi, baris baru, atau karakter apa pun yang memiliki arti khusus pada shell - gunakan jawaban ini sebagai gantinya untuk hasil yang dapat diandalkan)

Catatan

  • catcon cat membuat file. Itu juga mencetak isinya.
  • Menggunakan substitusi perintah, command2 $(command1)Anda dapat meneruskan output dari command1( cat list...) ke command2( cat) yang menyatukan file.
  • Kemudian gunakan pengalihan >>untuk mengirim output ke file alih-alih mencetak ke stdout. Jika Anda ingin melihat hasilnya, gunakan tee:

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

(Saya telah menggunakan >>bukannya >dan teedengan -aberalih dalam kasus file Anda sudah ada - ini menambahkan ke file bukannya Timpa, jika sudah ada)


1
@Zanna mengutip pergantian perintah untuk menghindari pemisahan kata, seperti"$(cat list_of_files.txt)"
Sergiy Kolodyazhnyy

4
@Ergika jika pemisahan kata tidak dilakukan, maka catdapatkan seluruh daftar sebagai satu argumen.
muru

@muru OK, bagaimana kita menangani nama file yang berisi spasi, lalu?
Sergiy Kolodyazhnyy

1
@Serg atur IFS sesuai - lihat paragraf terakhir dari jawaban saya
muru

4

Meskipun GNU awkadalah utilitas pemrosesan teks, GNU memungkinkan menjalankan perintah shell eksternal melalui system()panggilan. Kita dapat memanfaatkan itu untuk keuntungan kita seperti:

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

Idenya di sini sederhana: kita membaca file baris demi baris, dan dari setiap baris kita membuat string yang diformat cat "File name.txt" , yang kemudian diteruskan ke system().

Dan ini dia beraksi:

$ 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

Jadi kami telah melakukan sebagian besar tugas di sana - kami mencetak semua file dalam daftar. Sisanya sederhana: redirect output akhir ke file dengan >operator ke file ringkasan.

awk '{cmd=sprintf("cat \"%s\"",$0); system(cmd)}' file_list.txt > output.txt
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.