【问题标题】:How to remove the last characters in a file name using Bash?如何使用 Bash 删除文件名中的最后一个字符?
【发布时间】:2019-10-13 23:07:42
【问题描述】:

我在一个文件夹中有几个.txt 文件,它们的名称如下:

file1.txt
file2.txt
file2.txt_newfile.txt
file3.txt
file4.txt
file4.txt_newfile.txt
file5.txt_newfile.txt
...

我正在尝试从文件名中删除 _newfile.txt。如果文件存在,它应该被新文件覆盖(例如,file2.txt 将被替换,但 file5.txt 将被重命名)。

预期输出:

file1.txt
file2.txt # this was file2.txt_newfile.txt
file3.txt
file4.txt # file4.txt_newfile.txt
file5.txt #file5.txt_newfile.txt
...

我尝试了以下代码:

for i in $(find . -name "*_newfile.txt" -print); do 
mv -f "$file" "${file%????????????}"
done

但是,我收到以下错误:

mv: rename  to : No such file or directory

我做错了什么,如何重命名这些文件?

【问题讨论】:

  • 我会使用rename -n -f -s _newfile '' *newfile.txt

标签: bash rename file-rename


【解决方案1】:

您正在使用find 的输出填充变量i,但在mv 调用中引用了未声明的变量file。所以它扩展为mv -f '' '',这就是为什么你会得到一个没有这样的文件或目录错误。

你最好这样做:

find -type f -name '*_newfile.txt' -exec sh -c '
for fname; do
  mv -- "$fname" "${fname%_newfile.txt}"
done' _ {} +

如果这些文件都在同一个文件夹中,你甚至不需要find,只需要一个for循环就可以了:

for fname in *_newfile.txt; do
  mv -- "$fname" "${fname%_newfile.txt}"
done

【讨论】:

    【解决方案2】:

    对于很多人来说可能是一个不寻常的解决方案,但对我来说这是一个典型的 vi 工作。 很多人可能不记得了,您可以通过 shell 将 vi 缓冲区的内容通过管道传输,甚至可以使用调试输出 (sh -x)。

    我在这种或类似的情况下做什么,我不想浪费太多时间去思考很酷的正则表达式或 shell 诡计......务实的方式...... vi 支持你 ;-)

    我们开始吧:

    1. enter directory with those files that you want to rename
    2. start vi
    3. !!ls *_newfile.txt
    note: the !! command prompts you at the bottom to enter a command, the output of the ls command fills the vi buffer
    4. dG
    deletes all lines from your position 1 to the end of buffer, with a copy of it in the yank buffer
    5. PP
    paste 2 times the yank buffer
    6. !G sort
    !G prompts you at the bottom to pipe the buffer through sort
    now you have all the lines double to save the work of typing filename again
    7. with a combination of JkJk
    you join the lines, so you have now the filename 2 times in a line like here:
    file2.txt_newfile.txt file2.txt_newfile.txt
    8. now add a mv command at the beginning of each line using an ex command
    :%s/^/mv /
    9. now remove the not needed trailing "_newfile.txt", again with an ex command
    :%s/_newfile.txt$//
    Now you have i.e. the following line(s) in the vi buffer:
    mv file2.txt_newfile.txt file2.txt
    10 back to line 1 to that you feed the whole buffer to the shell in the next step
    1G
    11. feed the shell commands to the shell and show some debug command
    !G sh -x
    12. check the results in the folder within vi, you will get the output of the ls command into the buffer
    !!ls -l
    

    终于退出vi了。

    乍一看可能有很多步骤,但是如果您知道 vi,那么这会非常快,而且您还有一个额外的优势,即您可以将说明保存到文件中以用于文档目的或工作出来创建一个脚本等。

    【讨论】:

    • 8.应该是“现在在每一行的开始添加一个mv命令”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-17
    • 2013-09-22
    • 1970-01-01
    相关资源
    最近更新 更多