保持* nix格式

时间:2017-07-11 19:14:07

标签: linux bash shell vim sh

我的代码有效,但不是我想要的方式。基本上,我的代码所做的是它通过当前目录查找,搜索文件夹,并在这些文件夹中查看文件。如果其中一个文件扩展名是$ Example变量的值,那么它应该删除具有相同开始文件名的所有其他文件,而不管扩展名如何,并将具有$ Example扩展名的文件扩展名重命名为相同的名称,只是没有$示例扩展名。这是代码:

#!/bin/sh
set -o errexit
Example=dummy
for d in *; do
    if test "$(ls -A "$d" 2>/dev/null)"; then
        if [ $(ls -1 ${d}/*.$Example 2>/dev/null | wc -l) -ge 1 ]; then
            cd $(pwd)/$d;
            for f in *.$Example; do
                fileName="${f%.$Example}";
                mv "$f" "${f%.$Example}";
                #tr "\r" "\n" < "${f%.$Example}" > "${f%.$Example}"
                listToDelete=$(find -name "$fileName.*");
                for g in $listToDelete; do
                    rm $g;
                done;
            done;
            cd ..;
        fi;
    fi;
done

正在使用的文件已在VIM中创建,因此应该具有Linux格式,而不是Windows格式。出于某种原因,一旦剥离扩展,使用此代码,它将使用\r格式化,并且文件无法运行。我添加了我的临时解决方案所在的注释,但我想知道是否有某种方法可以改变mv函数以保持Linux格式,或者可能有另一种方法来实现我想要的。感谢

2 个答案:

答案 0 :(得分:1)

  

正在使用的文件是在VIM中创建的,因此应该使用Linux格式,而不是Windows格式。

这对正在使用的行分隔符没有影响。

但我可以想到3种不同的可能原因。

ViM替换

\r\n可能已混淆,或者Windows行分隔符(\r\n)可能已被错误地条带化。如果您只是尝试在某些时候转换Windows行分隔符,请将它们转换为Unix行分隔文件,如果可能,请使用dos2unix代替sedvim魔法,然后编辑它们。如果文件正在使用ViM添加或替换行分隔符,请记住在ViM行中使用\n搜索行分隔符并替换为\r,因为ViM只是将文件数据加载到缓冲区中。例如%s/\n/somestring/%s/somestring/\r/g

<强> Cygwin的

如果您正在使用Cygwin,我很确定使用Windows行分隔符默认使用ViM,但您可以将其更改为Unix行分隔符。不记得如何摆脱我的头顶。

ViM默认行分隔符

如果您使用的是GNU / Linux系统,不确定如何发生这种情况,但可以使用:e ++ff=unix

将指定用于ViM的默认行分隔符指定给Unix

答案 1 :(得分:0)

这个答案没有解决脚本源代码中可能存在迷路\r的问题,而是提供了另一种方法来做我认为是用户想要实现的目标:

#!/bin/bash

ext='dummy'
tmpfile=$(mktemp)

find . -type f -name "*.$ext" \
    -execdir bash -x -c \
        'cp "$3" "$2" &&
         tee "${3%.$1}"* <"$2" >/dev/null' bash "$ext" "$tmpfile" {} \;

rm -f "$tmpfile"

这将查找具有给定扩展名的所有文件,并为每个文件执行

cp "$3" "$2" && tee "${3%.$1}"* <"$2" >/dev/null
  • $1将是没有点的扩展名。
  • $2将是临时文件的名称。
  • $3将成为找到的文件。

该命令将首先将找到的文件复制到临时文件,然后它将通过tee提供此临时文件,该文件将其内容复制到具有相同前缀的所有文件(${3%.$1}将剥离从找到的文件名扩展名${3%.$1}*将扩展到同一目录中具有相同前缀的所有文件。)

find的大多数现代实现都支持-execdir,其作用类似于-exec,区别在于给定的实用程序将在找到的名称的目录中执行。此外,{}将是找到的东西的无路径基本名称。

给定目录中的以下文件:

$ ls test/
f1.bar   f1.foo   f2.bar   f2.foo   f3.bar   f3.foo
f1.dummy f1.txt   f2.dummy f2.txt   f3.dummy f3.txt

此脚本执行以下操作:

$ bash -x script.sh
+ ext=dummy
++ mktemp
+ tmpfile=/tmp/tmp.9v5JMAcA12
+ find . -type f -name '*.dummy' -execdir bash -x -c 'cp "$3" "$2" &&
         tee "${3%.$1}"* <"$2" >/dev/null' sh dummy /tmp/tmp.9v5JMAcA12 '{}' ';'
+ cp f1.dummy /tmp/tmp.9v5JMAcA12
+ tee f1.bar f1.dummy f1.foo f1.txt
+ cp f2.dummy /tmp/tmp.9v5JMAcA12
+ tee f2.bar f2.dummy f2.foo f2.txt
+ cp f3.dummy /tmp/tmp.9v5JMAcA12
+ tee f3.bar f3.dummy f3.foo f3.txt
+ rm -f /tmp/tmp.9v5JMAcA12

从调用-x(以及命令行上的bash)中删除bash以禁用跟踪。

我使用bash而不是sh,因为我的sh无法正确理解${3%.$1}