2013-09-30 12 views
5

Tôi đang cố gắng xóa danh sách các từ cụ thể khỏi tất cả các tệp của tôi bằng một thư mục nhất định và thay thế chúng bằng không có gì.Xóa danh sách các từ khỏi tên tệp

Vì vậy:

nội dung hấp dẫn này 720p BLAH FOO BANG OOO - 30.9.2013.mp4

trở thành:

này awesome Content - 30.9.2013.mp4

Bây giờ, các công trình sau rất tuyệt vời cho một vây d và thay thế một từ.

find path/to/folder/ -maxdepth 3 -name '*.*' -execdir bash -c 'mv -i "$1" "${1//foo/}"' bash {} \; 

Tôi cũng đã thử nhiều lần nhưng điều này có vẻ như một cách rất dài để làm điều đó và dường như tôi gặp vấn đề theo cách này.

Couple của vấn đề tôi có:

  • Muốn nó là trường hợp nhạy cảm
  • Cần "$ {1 // foo /}" để chỉ một danh sách
  • Di chuyển không gian trắng nếu lớn hơn 1

Cố gắng chạy tập lệnh này dưới dạng tập lệnh bash trên cronjob.

Trừ khi có cách nào tốt hơn để xóa mọi thứ giữa "Nội dung tuyệt vời này" - "30.9.2013.mp4".

Được đánh giá cao.

Trả lời

4

Bạn có thể truy cập tên tệp dưới dạng biến bằng lệnh 'echo'. Khi đã xong, cách mạnh mẽ nhất để thực hiện các thay đổi mong muốn của bạn là sử dụng 'sed'. Bạn có thể chuỗi các lệnh sed với cờ '-e'. Là một phần của vòng lặp for trong bash, dòng này cho bạn một sự khởi đầu. Bạn cũng có thể sử dụng một dòng như thế này như là một phần của câu lệnh 'find' của bạn.

echo $fyle | sed -e 's/FOO//gI' -e 's/BANG//gI' 

Khi bạn có tên tệp mong muốn, bạn có thể chuyển chúng về tên gốc. Hãy cho tôi biết nếu bạn cần hướng dẫn cụ thể hơn.

CẬP NHẬT: Đây là giải pháp hoàn chỉnh hơn. Bạn sẽ phải điều chỉnh tập lệnh thành tên tệp của riêng mình, v.v.

for fyle in $(find . -name "*.*") 
do 
    mv -i $fyle `echo $fyle | sed -e 's/FOO//gI' -e 's/BANG//gI' ` 
done 

Cuối cùng, để thay thế nhiều ký tự khoảng trắng bằng một ký tự trắng, bạn có thể thêm lệnh sed khác. Dưới đây là một lệnh làm việc:

echo "file input.txt" | sed 's/ */ /g' 
+0

Dường như tôi là một newb hoàn chỉnh. Làm thế nào tôi sẽ thực hiện điều này vào lệnh tìm của tôi, thay thế lệnh mv? Ngoài ra, nếu tôi thêm I to -e 's/FOO // g' e.g. -e 's/FOO // Ig' sẽ bỏ qua độ nhạy trường hợp này. – Keelan

+1

Để làm cho trường hợp không nhạy cảm, hãy đặt một gI ở cuối. Tôi đã cập nhật bài đăng của mình. – philshem

+1

Tôi đã thêm một giải pháp hoàn chỉnh hơn. Vui lòng cho tôi biết cách thức hoạt động của bạn. – philshem

3

Một cách để làm điều này sẽ thêm một bước trung gian mà bạn tạo ra một tập tin với mv lệnh để đạt được điều này, và sau đó thực hiện tập tin đó. Tôi giả sử bạn có tệp chứa các từ bạn không muốn.

cd vào thư mục trước khi bắt đầu

# Create list of valid <file>s in file_list, and list of "mv <file> " commmands 
# in cmd_file 
ls | grep -f words_file | tee file_list | sed 's/\(.*\)/mv "\1" /g' > cmd_file 

# Create the sed statements using the words_file, store it to sed_commands 
# Then, apply the sed commands to file_list 
sed 's/\(.*\)/s\/\1\/\/g/g' words_file > sed_commands 
sed -f sed_commands file_list > new_file_names 

# Combine cmd_file and new_file_names to produce the full mv statements 
paste cmd_file new_file_names > final_cmds 

# To verify the commands 
cat final_cmds 

# Finally, execute it 
sh final_cmds 

Đây là những gì tôi có thể nghĩ ra, nó tránh bằng tay viết sed -e cho mỗi từ. Không chắc chắn nếu có một cách đơn giản hơn bằng cách sử dụng các tiện ích bash thông thường. Tất nhiên, bạn có thể sử dụng perl hoặc python và viết nó chính xác hơn.

Chỉnh sửa: Đơn giản hóa nó, đã bỏ đi với eval và xargs.

+0

Có vẻ đẹp, làm cách nào để chỉ định thư mục? – Keelan

+0

Tôi gặp lỗi khi chạy "$ sed 's /\(.*\)/ s \/\ 1 \/\/g' words_file> sed_commands" ---- lỗi này là: sed: -e expression # 1, char 19: unterminated 's 'lệnh –

+0

@Keelan cd vào thư mục trước khi bắt đầu. –

1

Một tập lệnh cho tác vụ. Nó chấp nhận ít nhất hai đối số, đầu tiên là danh sách các từ để xóa từ tên tập tin, và phần còn lại là các tập tin vào quá trình:

perl -MFile::Spec -MFile::Copy -e ' 
    $words = join(q{|}, split(q| |, shift)); 
    $words_re = qr{$words}i; 
    for $path (@ARGV) { 
     ($dummy, $dir, $f) = File::Spec->splitpath($path); 
     $f =~ s/$words_re//g; 
     $f =~ s/\s{2,}/ /g; 
     $newpath = File::Spec->catfile($dir, $f); 
     move($path, $newpath); 
     printf qq|[[%s]] renamed to [[%s]]\n|, $path, $newpath; 
    } 
' "720p BLAH FOO BANG OOO" tmp/user/*.mp4 

Trong thử nghiệm của tôi, tôi đã theo sản lượng:

[[tmp/user/This Awesome Content 720p BLAH FOO BANG OOO - 30.9.2013.mp4]] renamed to [[tmp/user/This Awesome Content - 30.9.2013.mp4]] 
+0

Tôi không biết perl chút nào vì vậy tôi nghĩ rằng điều này có lẽ nằm ngoài lĩnh vực của tôi. Tôi có thể chỉ định thư mục để tìm kiếm tệp không? – Keelan

+1

@Keelan: Có. Nhưng sau đó sử dụng một lệnh thay thế là nguy hiểm vì có thể sửa đổi các phần của đường dẫn. Nó sẽ cần một sửa chữa để sử dụng một mô-đun. – Birei

+0

Oh ok, tôi nghĩ rằng tôi sẽ ở lại rõ ràng sau đó. Perl sợ tôi. – Keelan

0

prename có thể hữu ích cho phần đổi tên tệp. stg tương tự:

find ... -exec prename 's/(deleteme1|deleteme2|…)//g' {} \; 
Các vấn đề liên quan