递归文本替换和文件扩展名重命名

时间:2019-08-30 18:52:48

标签: linux bash shell

我正在使用在Linux服务器上创建文本文件的应用程序。然后,我可以执行shell脚本(BASH 3.2.57),在该脚本中,我需要将文本文件从Unix行尾转换为DOS,并将文件扩展名从.txt更改为.log。

我目前有一个基于sed的命令来执行此操作。应用程序在运行时会重写此命令,以指向特定的文件夹和文件名,在此示例中,您会看到ABC(我所有示例中的所有大写3个字母都是变量,可以是3个字母)。

pushd /rootfolder/parentfolder/ABC/
sed 's/$/\r/' prABC.txt > prABC.log
popd

这样做的问题是,如果用户针对两个不同的组(例如ABC和DEF)同时运行应用程序,则脚本将在DEB变量被ABC触发并执行其操作之前被DEF变量覆盖。东西与文件。另外,无论如何,.txt都保留在文件夹中,我希望将其删除。

我的一个朋友提出了以下代码,如果它确定是我们的最佳解决方案,那么它似乎可以工作,但我想并希望我们有一种更清洁,更动态的方法来执行此操作。另外,当前方法还要求,当我的用户决定添加GHI目录和文件时,我现在必须更新代码,我可以对应用程序进行编程以为我执行此操作,但是我不希望每次都必须重写此脚本该应用程序想要使用它。

pushd /rootfolder/parentfolder/ABC
if [[ -f prABC.txt ]]
  then
    sed 's/$/\r/' prABC.txt > prABC.log
    rm prABC.txt
fi
popd

pushd /rootfolder/parentfolder/DEF
if [[ -f prABC.txt ]]
  then
    sed 's/$/\r/' prABC.txt > prABC.log
    rm prABC.txt
fi
popd

我想随时从我的应用程序中调用此脚本,它会在/ rootfolder / parentfolder /目录下找到任何名为pr * .txt的文件(如果在其搜索中必须包含父文件夹,而该文件不会是问题),然后将行尾从LF转换为CRLF,并将文件的扩展名从.txt更改为.log。

我已经进行了大量搜索,并找到了解决方案,但并非完全符合我的需要,我想确保它尽可能安全(使用“ find with for”的问题。我不知道在此版本上安装了什么实用程序,因此我希望使其尽可能保持基本/可支持的功能:)

1 个答案:

答案 0 :(得分:2)

您几乎永远不需要在脚本中使用pushdpopd。实际上,您也很少需要cd

#!/bin/bash
for d in /rootfolder/parentfolder/ABC /rootfolder/parentfolder/DEF
do
  if [[ -f "$d/prABC.txt" ]]
  then
    sed 's/$/\r/' "$d/prABC.txt" > "$d/prABC.log" &&
    rm "$d/prABC.txt"
  fi
done

回想一下a && b是速记

if a; then
    b
fi

换句话说,如果sed失败(因为无法读取源文件或无法写入目标),我们就不会rm源文件。应该已经有一条错误消息,所以我们不再添加其他错误消息。

这不仅更加简洁,而且如果您决定重命名而不是删除旧文件,或者您想过滤掉sed中所有包含“牛肉”的行,则更改起来也更加容易。脚本。通常,您应该避免重复代码;另请参见the DRY principle on Wikipedia.

如果在Unix上的文件中要求DOS行结尾,则某处存在严重错误。