Hapus jalur dari output perintah find

29

Saya memiliki skrip bash untuk menyebarkan kode dari lingkungan beta ke lingkungan produksi tetapi saat ini saya harus menambahkan daftar file ke file txt manaully dan kadang-kadang saya melewatkan beberapa. Pada dasarnya script deployment saya cat / loop menyalin file. (ekspor / impor db juga tapi itu tidak relevan..lol)

Bagaimanapun, saya ingin menggunakan findperintah untuk menghasilkan daftar file yang dimodifikasi dalam 14 hari terakhir. Masalahnya adalah saya harus menghapus jalur ./agar skrip penerapan berfungsi.

Berikut adalah contoh penggunaan perintah find:

temukan. -type f -mtime -14> deploy.txt

Inilah baris yang digunakan kucing deploy.txtdalam skrip penerapan saya:

for i in `cat deploy.txt`; do cp -i /home/user/beta/public_html/$i /home/user/public_html/$i; done

Adakah cara untuk mencapai hal ini menggunakan bash scripting?

Terima kasih!

Mikey1980
sumber
3
Apakah ada alasan Anda tidak bisa menggunakan rsync hanya untuk ini? Kedengarannya seolah-olah Anda mungkin mencoba menemukan kembali roda dan membuatnya menjadi segitiga.
ThatGraemeGuy
Namun poin yang valid sebelum penyebaran deploy.txt ditinjau dan segala sesuatu yang perlu diperbaiki akan dihapus
Mikey1980
1
Mungkin menjalankan rsync dalam --dry-runmode dan output itu ke file untuk ditinjau?
Zoredache

Jawaban:

36

Anda dapat menggunakan -printfopsi baris perintah dengan %funtuk mencetak hanya nama file tanpa informasi direktori

find . -type f -mtime -14 -printf '%f\n' > deploy.txt

atau Anda dapat menggunakan sed untuk menghapus ./

find . -type f -mtime -14 | sed 's|^./||' >deploy.txt
Iain
sumber
Saya percaya Anda harus melarikan diri /..
EEAA
5
Tidak ketika Anda gunakan |sebagai pembatas.
user9517 mendukung GoFundMonica
3
Menggunakan %fakan menghapus semua direktori, bukan hanya ./. Ini akan merusak skrip penerapannya jika ada file yang dikembalikan oleh findterletak di subdirektori.
James Sneeringer
2
@ Iain Anda harus melarikan diri .. Dan mungkin yang terbaik untuk menggunakan jangkar awal:s|^\./||
James O'Gorman
12
Gunakan %Psebagai ganti %f. Ini hanya memotong jalur yang diberikan di baris perintah.
Benar
11

The ./harus tidak berbahaya. Sebagian besar program akan memperlakukan /foo/bardan /foo/./barsetara. Saya menyadari itu tidak terlihat sangat bagus, tetapi berdasarkan apa yang Anda posting, saya tidak melihat alasan mengapa itu akan menyebabkan skrip Anda gagal.

Jika Anda benar-benar ingin menanggalkannya, sedmungkin ini adalah cara terbersih:

find . -type d -mtime 14 | sed -e 's,^\./,,' > deploy.txt

Jika Anda menggunakan sistem dengan GNU find (mis. Kebanyakan sistem Linux), Anda dapat melakukannya dalam satu kesempatan dengan find -printf:

find . -type d -mtime 14 -printf "%P\n" > deploy.txt

The %Preturn path lengkap dari setiap file yang ditemukan, dikurangi jalan yang ditentukan pada baris perintah, sampai dengan dan termasuk garis miring pertama. Ini akan mempertahankan subdirektori dalam struktur direktori Anda.

James Sneeringer
sumber
1
The ./prefix sebenarnya fitur; tanpa itu, piping output ke perintah lain tidak akan berfungsi dengan baik misalnya untuk nama file yang dimulai dengan tanda hubung.
tripleee
1
@ tripleee - Saya mengerti kegunaannya, tapi OP secara khusus bertanya bagaimana cara menghapusnya karena itu menyebabkan masalah untuk skrip deployment-nya. Tentu, mungkin ada cara yang lebih baik untuk melakukan apa yang perlu dia lakukan, tapi itu lubang kelinci jauh di luar ruang lingkup apa yang diminta.
James Sneeringer
7

Mengapa Anda perlu melepas ./? Ini sah untuk dimiliki di jalur. Begitu

cp -i dir1/./somefile dir2/./somefile

tidak apa-apa!

Tetapi jika Anda ingin menghapus nama direktori di find Anda dapat menggunakan %Parg to -printf.

man find (1) mengatakan:

         %P     File's name with the name of the  command  line  argument
                 under which it was found removed.

Sebuah contoh

$ find other -maxdepth 1
other
other/CVS
other/bin
other/lib
other/doc
other/gdbinit
$ find other -maxdepth 1 -printf "%P\n"

CVS
bin
lib
doc
gdbinit

Pikirkan baris kosong pertama! Jika Anda ingin menghindarinya gunakan-mindepth 1

$ find other -mindepth 1 -maxdepth 1 -printf "%P\n"
CVS
bin
lib
doc
gdbinit
Benar
sumber
3

Anda punya beberapa opsi. Anda dapat menggunakan -printfopsi dalam find untuk hanya mencetak nama file, atau Anda dapat menggunakan alat seperti sed untuk menghapusnya ./.

# simply print out the filename, will break if you have sub-directories.
find . -mtime -14 -printf '%f\n'

# strip a leading ./
find .  -mtime -14 | sed -e 's/^\.\///'
Sakit kepala
sumber
Bisakah Anda memberi saya contoh penggunaannya? Maaf, linux tidak benar-benar forte saya
Mikey1980
2
Lihat lagi, ada contohnya.
Zoredache
Setuju - coba saja, Anda tidak akan melukai apa pun yang menjalankan kombinasi find dan sed.
EEAA
3

Solusi "find -printf" tidak akan berfungsi pada FreeBSD karena find tidak memiliki opsi seperti itu. Dalam hal ini AWK dapat membantu. Ini mengembalikan nama belakang ($ NF), sehingga dapat bekerja pada kedalaman apa pun.

find /usr/local/etc/rc.d -type f | awk -F/ '{print $NF}'

PS: diambil dari buku D.Tansley "Linux and Unix shell programming"

pengguna221341
sumber
2

Solusi cepat, jika saya mengerti benar pertanyaannya, gunakan cutpada output dari findperintah:

$> find . -type f -mtime -14 | cut -b 3- > deploy.txt

Ini akan menghapus karakter pertama menjadi dari setiap baris hasil (dalam kasus Anda ./). Mungkin bukan solusi terbaik, tetapi berhasil dalam skenario Anda.

Alessandro Dotti Contra
sumber
1

sed sangat cocok untuk hal semacam ini.

$ find . -type f -mtime -14 find . | sed 's/^\.\///' > deploy.txt
EEAA
sumber
1

Saya tidak tahu nama file seperti apa yang sedang kita bicarakan, tetapi apa pun dengan spasi atau baris baru membuat sebagian besar solusi beresiko.

Saran saya adalah menggunakan ekspansi parameter shell untuk menghapus karakter dari setiap nama file:

find . -mtime -14 -exec sh -c 'printf "${0#./}\n"' {} \; >deploy.txt

Jika Anda benar-benar menyukai pipa, Anda bisa menggunakan pembatas "aman", seperti nol, dengan xargs untuk menerima setiap nama file:

find . -mtime -14 -print0 | xargs -0 -n 1 sh -c 'printf "${0#./}\n"' >deploy.txt

Ingat bahwa output ini BUKAN pembatas nol, jadi walaupun mungkin cukup untuk pemeriksaan bola mata, tidak ada solusi yang menghasilkan file deploy.txt yang aman digunakan untuk otomatisasi, kecuali Anda sangat yakin dengan sumber Anda nama file.

ghoti
sumber