当前目录文件批量重命名:移除.tsv后字符的问题求助
Fixing the File Renaming Issue: Removing Everything After .tsv
Your original script ran into two key problems that caused most files to "disappear" and only 15 to process correctly:
- Unreliable fixed character truncation: Removing exactly 14 characters only works if every file has exactly 14 characters after
.tsv—but your examples show some have fewer (likeALLT194_TAB20.tsv_20180117_0083has 13 characters after.tsv). This meant you accidentally chopped off parts of the actual filename for some files. - Loop reprocessing renamed files: Using
for i in *makes the shell re-expand the file list as you rename files. This leads to some files being processed multiple times, or overwriting each other (since two original files might end up with the same truncated name, causing one to overwrite the other).
Here are two reliable, safe solutions to fix this:
Solution 1: Bash Native Parameter Expansion (Fast & Efficient)
This uses bash's built-in string manipulation to truncate correctly, and we first collect all target files into an array to avoid reprocessing renamed files:
# Collect all files with .tsv followed by extra characters into an array target_files=(*.tsv_*) for file in "${target_files[@]}" do # Keep everything up to and including .tsv new_name="${file%.tsv*}.tsv" # Only rename if the new name is different to avoid errors if [ "$file" != "$new_name" ]; then mv -- "$file" "$new_name" fi done
Breakdown:
target_files=(*.tsv_*): Grabs all files matching your pattern into an array, so we work with the original list of files once (no reprocessing renamed files).${file%.tsv*}: Removes the shortest suffix starting with.tsv, leaving the part before.tsv. We add.tsvback to keep the extension intact.mv -- "$file" "$new_name": The--ensures filenames starting with-are handled correctly, and quoting prevents issues with spaces or special characters.
Solution 2: Using Sed (If You Prefer Text Processing)
If you'd rather use sed, this version correctly truncates everything after .tsv regardless of length, while avoiding reprocessing issues:
target_files=(*.tsv_*) for file in "${target_files[@]}" do new_name=$(echo "$file" | sed 's/\.tsv.*$/.tsv/') if [ "$file" != "$new_name" ]; then mv -- "$file" "$new_name" fi done
Breakdown:
sed 's/\.tsv.*$/.tsv/': This regex replaces.tsvfollowed by any characters until the end of the string with just.tsv, ensuring we keep only the part up to and including.tsv.
Both solutions will safely rename all your files without losing any data.
内容的提问来源于stack exchange,提问作者Amit Prasad
相关产品推荐
相关产品推荐

