GNU/Linux >> Belajar Linux >  >> Linux

Bagaimana cara mengurai output dari perintah find ketika nama file memiliki spasi di dalamnya?

Idealnya Anda tidak melakukannya sama sekali, karena mem-parsing nama file dengan benar dalam skrip shell selalu sulit (perbaiki untuk spasi, Anda masih akan mengalami masalah dengan karakter tersemat lainnya, khususnya baris baru). Ini bahkan terdaftar sebagai entri pertama di halaman BashPitfalls.

Yang mengatakan, ada cara untuk hampir melakukan apa yang Anda inginkan:

oIFS=$IFS
IFS=$'\n'

find . -name '*.txt' | while read -r i; do
  # use "$i" with whatever you're doing
done

IFS=$oIFS

Ingat juga untuk mengutip $i saat menggunakannya, untuk menghindari hal-hal lain yang menafsirkan ruang nanti. Ingatlah juga untuk menyetel $IFS kembali setelah menggunakannya, karena tidak melakukannya akan menyebabkan kesalahan yang membingungkan nantinya.

Ini memang memiliki satu peringatan lain:apa yang terjadi di dalam while loop dapat terjadi dalam subkulit, tergantung pada shell persis yang Anda gunakan, sehingga pengaturan variabel mungkin tidak bertahan. for versi loop menghindari itu tetapi dengan harga itu, bahkan jika Anda menerapkan $IFS solusi untuk menghindari masalah dengan spasi, Anda kemudian akan mendapat masalah jika find mengembalikan terlalu banyak file.

Pada titik tertentu, perbaikan yang benar untuk semua ini adalah melakukannya dalam bahasa seperti Perl atau Python, bukan shell.


Gunakan find -print0 dan kirimkan ke xargs -0 , atau tulis program C kecil Anda sendiri dan kirimkan ke program C kecil Anda. Inilah yang -print0 dan -0 diciptakan untuk.

Skrip Shell bukan cara terbaik untuk menangani nama file dengan spasi di dalamnya:Anda bisa melakukannya, tetapi akan menjadi kikuk.


Anda dapat menyetel "pemisah bidang internal" (IFS ) ke selain ruang untuk pemisahan argumen pengulangan, mis.

ORIGIFS=${IFS}
NL='
'
IFS=${NL}
for i in $(find . -name '*.txt'); do
    IFS=${ORIGIFS}
    #do stuff
done
IFS=${ORIGIFS}

Saya mereset IFS setelah digunakan di find, kebanyakan karena tampilannya bagus, menurut saya. Saya belum melihat masalah dalam mengaturnya ke baris baru, tapi menurut saya ini "lebih bersih".

Metode lain, tergantung pada apa yang ingin Anda lakukan dengan output dari find , adalah menggunakan -exec secara langsung dengan find perintah, atau gunakan -print0 dan kirimkan ke xargs -0 . Dalam kasus pertama find menangani nama file yang keluar. Di -print0 kasus, find mencetak hasilnya dengan pemisah null, lalu xargs terpecah dalam hal ini. Karena tidak ada nama file yang dapat berisi karakter itu (yang saya tahu), ini juga selalu aman. Ini sebagian besar berguna dalam kasus sederhana; dan biasanya bukan pengganti yang bagus untuk for lengkap lingkaran.


Linux
  1. Bagaimana Menghentikan Perintah Temukan Setelah Pertandingan Pertama?

  2. Bagaimana Mengenalinya Versi Os X Saya Dari Baris Perintah?

  3. Bagaimana Cara Mengatur Variabel Sama Dengan Output Dari Perintah Di Grub2?

  1. Cara Menggunakan Perintah find Linux untuk Menemukan File

  2. Bagaimana Anda menentukan nama file di dalam zip saat membuatnya di baris perintah dari pipa?

  3. Cara menggabungkan perintah 'tar' dengan 'find'

  1. Bagaimana cara mengetahui apa yang dilakukan perintah Linux

  2. Bagaimana Cara Menetapkan Output Perintah Ke Variabel Shell?

  3. Apa perbedaan antara perintah locate dan find di Linux?