Bagaimana cara mengganti nama semua file dengan karakter dan spasi khusus dalam direktori?

10

Bagaimana saya bisa mengganti nama semua file dalam direktori tertentu di mana file berisi spasi kosong dan karakter khusus ($ dan @) dalam nama mereka?

Saya mencoba renameperintah sebagai berikut untuk mengganti semua spasi dan karakter khusus dengan _:

$ ls -lrt
total 464
-rwxr-xr-x. 1 pmautoamtion pmautoamtion 471106 Jul 17 13:14 Bharti Blocked TRX Report Morning$AP@20150716.csv


$ rename -n 's/ |\$|@/_/g' *
$ ls -lrt
total 464
-rwxr-xr-x. 1 pmautoamtion pmautoamtion 471106 Jul 17 13:14 Bharti Blocked TRX Report Morning$AP@20150716.csv
$

Perintah ini berfungsi tetapi tidak akan membuat perubahan apa pun dalam nama file dan tidak akan mengembalikan kesalahan apa pun juga. Bagaimana cara memperbaikinya dan apakah ada cara lain juga?

Ankit Vashistha
sumber
1
Anda mungkin mengharapkan skrip rename perl (ref: manpages.ubuntu.com/manpages/dapper/man1/prename.1.html ) tetapi sebaliknya mendapatkan rename util-linux, yang tidak bekerja dengan cara yang sama.
Jeff Schaller

Jawaban:

10

The -nbendera untuk

--tidak ada tindakan

Tanpa Tindakan: tampilkan file apa yang akan diubah namanya.

Jadi normal jika Anda tidak memiliki perubahan.

Mengenai perintah Anda, itu berfungsi untuk saya:

$ touch "a @ test"
$ ls
a @ test
$ rename -n 's/ |\$|@/_/g' *
a @ test renamed as a___test

Mungkin tergantung pada cangkang Anda, Anda harus melarikan diri |

$ rename -n 's/ \|\$\|@/_/g' *

Atau Anda dapat menggunakan […]notasi untuk mengelompokkan karakter:

$ rename -n 's/[ @\$]/_/g' *
fredtantini
sumber
1
Saya mencoba ketiganya tanpa opsi -n dan tetap saja tidak akan mengubah nama file. Saya tidak memberikan kesalahan untuk 3 jenis yang disebutkan di atas. Mungkin perintah ganti nama tidak berfungsi karena suatu alasan. Apakah ada cara lain untuk mengubah semua file dalam direktori dengan spasi atau $ atau @ dalam namanya?
Ankit Vashistha
@AnkitVashistha rename -n 's/./_/g' *menghasilkan sesuatu?
fredtantini
Itu tidak memberikan apa-apa, tidak ada output, tidak ada kesalahan. Itu hanya mendarat di baris perintah berikutnya.
Ankit Vashistha
rename juga tidak berfungsi bagi saya untuk mengganti (spasi) atau ':' di Ubuntu 18.04, Bash 4.4.20 (1) -release
Ouss
7

Anda dapat mencoba seperti ini:

for file in ./*Block*                                       
do echo mv "$file" "${file//[ ()@$]/_}"
done

Jika Anda puas dengan hasilnya, hapus echosebelum mvuntuk benar-benar mengganti nama file.

don_crissti
sumber
Salah satu solusi terbaik yang telah saya lalui, saya sudah mencoba untuk ini begitu lama
Sushin Pv
2

mencari skrip yang ganteng untuk menghapus karakter khusus serta karakter khusus Jerman, menggantikannya dengan yang universal untuk tidak menghapus informasi yang berguna. Saya telah memperbarui versi terakhir dari skrip yang memiliki beberapa masalah kecil yang mengakibatkan:

#!/bin/bash

for file in ./*
do
  infile=`echo "${file:2}"|sed  \
         -e 's|"\"|"\\"|g' \
         -e 's| |\ |g' -e 's|!|\!|g' \
         -e 's|@|\@|g' -e 's|*|\*|g' \
         -e 's|&|\&|g' -e 's|]|\]|g' \
         -e 's|}|\}|g' -e 's|"|\"|g' \
         -e 's|,|\,|g' -e 's|?|\?|g' \
         -e 's|=|\=|g'  `
  outfileNOSPECIALS=`echo "${file:2}"|sed -e 's|[^A-Za-z0-9._-]|_|g'`
  outfileNOoe=`echo $outfileNOSPECIALS| sed -e 's|ö|oe|g'`
  outfileNOae=`echo $outfileNOoe| sed -e 's|ä|ae|g'`
  outfileNOue=`echo $outfileNOae| sed -e 's|ü|ue|g'`
  outfileNOOE=`echo $outfileNOue| sed -e 's|Ö|OE|g'`
  outfileNOAE=`echo $outfileNOOE| sed -e 's|Ä|AE|g'`
  outfileNOUE=`echo $outfileNOAE| sed -e 's|Ü|UE|g'`
  outfileNOss=`echo $outfileNOUE| sed -e 's|ß|ss|g'`
  outfile=${outfileNOss}
  if [ "$infile" != "${outfile}" ]
  then
        echo "filename changed for " $infile " in " $outfile
        mv "$infile" ${outfile}
  fi
done

exit

yang menghasilkan:

masukkan deskripsi gambar di sini

@don_crissti: Dia melakukan hokus-pokus dengan infile karena linux akan memiliki masalah sendiri dengan penanganan karakter khusus ketika memindahkan nama file.

Matthias R. Wiora
sumber
1
karakter spesial ? yang mana
don_crissti
Space, At symbol, Ampersand ....
Matthias R. Wiora
Tidak ada masalah memindahkan file dengan nama yang berisi karakter khusus (termasuk baris baru) ... Anda mungkin tidak terbiasa dengan shell (dan btw, ini tidak ada hubungannya dengan linux, itu adalah fitur shell ... )
don_crissti
mh oke - Anda mungkin benar
Matthias R. Wiora
1

Karena renameperintah itu tidak berfungsi untuk saya karena alasan yang tidak diketahui dan saya tidak mendapatkan jawaban lain untuk pertanyaan saya, saya sendiri mencoba melakukan upaya untuk membuat penggantian nama menjadi mungkin. Ini mungkin bukan pendekatan terbaik untuk mengubah nama file tetapi berhasil bagi saya dan inilah mengapa saya ingin mempostingnya sebagai jawaban sehingga jika orang lain membaca ini mungkin mendapatkan bantuan untuk mengubah nama file seperti yang saya lakukan.

Sekarang bagi saya, saya tahu bahwa semua file akan memiliki teks tertentu dalam nama mereka yang merupakan kata "Blokir". Berikut ini adalah nama file sebelum penggantian nama dilakukan:

anks@anks:~/anks$ ls -lrt
total 4
-rw-r--r-- 1 anks anks   0 Jul 25 14:47 Bharti TRX Block Report$AP@12Jul15.csv
-rw-r--r-- 1 anks anks   0 Jul 25 14:47 Bharti TRX Block Report$HP@12Jul15.csv
-rw-r--r-- 1 anks anks   0 Jul 25 14:47 Bharti TRX Block Report$CH@12Jul15.csv
-rw-r--r-- 1 anks anks   0 Jul 25 14:47 Bharti TRX Block Report$KK@12Jul15.csv
-rw-r--r-- 1 anks anks   0 Jul 25 14:48 Bharti TRX Block Report$UW@12Jul15.csv

Sekarang saya telah menulis skrip shell kecil untuk memungkinkan ini. Berikut ini adalah kode:

#!/bin/bash

PATH="/home/ebfijjk/anks"

# Put the old filenames in a file.
ls $PATH | grep Block >> oldValues

# Put the new names without " " or "@" or "$" in another file
cat oldValues | sed 's/\$/_/g' | sed 's/\@/_/g' | sed 's/ /_/g' >> newValues

# Create a new file with Old names and New names seperated by a #.
paste -d'#' oldValues newValues >> oldAndNew

# Read the file with both old and new names and rename them with the new names.
while IFS='#'; read oldValue newValue
do
    mv "$oldValue" "$newValue"

done < oldAndNew

rm oldValues newValues oldandNew

Dan itu saja, ketika saya menjalankan skrip, itu mengubah nama semua nama file yang memiliki spasi kosong ( ) $atau @dengan _alih - alih karakter ini.

Ankit Vashistha
sumber
Anda dapat menggantinya cat foo | sed S1 | sed S2 | sed S3 >> bardengansed -e S1 -e S2 -e S3 foo >> bar
Archemar
2
@Archemar - atau cukup sed 's/[ ()@$]/_/g'ataused 'y/ ()@$/_____/'
don_crissti
Terima kasih don_crissti dan Archemar atas komentar dan saran Anda.
Ankit Vashistha
1

Yang ini hanya menghapus karakter khusus dari nama file

for file in *; do mv "$file" `echo $file | tr -cd '.A-Za-z0-9_-'` ; done
Námásté Egész-ség.mkv --> NmstEgsz-sg.mkv

menempatkan echosetelah ; dotes sebelumnya, seperti:

for file in *; do echo mv "$file" `echo $file | tr -cd '.A-Za-z0-9_-'` ; done

Solusi lain:

rename -v 's/[^a-zA-Z0-9\.\s_-]//g' *.* && rename -v 's/[\s]/_/g' *.*
Námásté Egész-ség.mkv --> Nmst_Egsz-sg.mkv

-n pilihan untuk menguji sebelumnya.

Eapo
sumber
0

Saya telah mencari solusi untuk masalah ini untuk sementara waktu sekarang. Saya bekerja pada sistem tertutup lama yang tidak dapat menginstal paket baru. Saya tidak punya renameperintah. Akhirnya saya menulis skrip yang tampaknya berfungsi dengan semua keyboard memasukkan karakter khusus. ~@#$%^&*()-_=+[]{}\|;:",<.>?' Script akan mengganti nama setiap file dan direktori di direktori saat ini. Itu akan menggantikan semua karakter khusus, kecuali -_.dengan _karakter. The outfile=garis dapat dimodifikasi untuk menggunakan karakter yang berbeda untuk penggantian jika diinginkan. Ganti |_|dengan |.|menggunakan .karakter misalnya.

#!/bin/bash

for file in ./*
do
  infile=`echo "${file:2}"|sed  \
         -e 's|"\"|"\\"|g' \
         -e 's| |\ |g' -e 's|!|\!|g' \
         -e 's|@|\@|g' -e 's|*|\*|g' \
         -e 's|&|\&|g' -e 's|]|\]|g' \
         -e 's|}|\}|g' -e 's|"|\"|g' \
         -e 's|,|\,|g' -e 's|?|\?|g' \
         -e 's|=|\=|g'  `
  outfile=`echo "${file:2}"|sed -e 's|[^A-Za-z0-9._-]|_|g'`
  mv "$infile" ${outfile} &
done

exit
ScriptKitty37
sumber
0

Bagi saya di Ubuntu 18.04 LTS dengan bash 4.4.20 (1) - lepaskan one-liner ini bekerja dengan baik untuk menghilangkan spasi, @,: # ...

Untuk menguji (perhatikan echoperintah:

for file in ./* ; do if [[ $file == *['!'\ :@#]* ]]; then echo mv "$file" "${file//[ #()@$:]/_}"; fi; done

Untuk mengeksekusi:

for file in ./* ; do if [[ $file == *['!'\ :@#]* ]]; then echo mv "$file" "${file//[ #()@$:]/_}"; fi; done
Ouss
sumber