Linux 保持*nix格式
我的代码可以工作,但不是我想要的方式。基本上,我的代码所做的就是查看当前目录,搜索文件夹,然后在这些文件夹中查看文件。如果其中一个文件扩展名是$Example变量的值,则它应删除具有相同起始文件名的所有其他文件,而不考虑扩展名,并将具有$Example扩展名的文件重命名为相同名称,而不使用$Example扩展名。代码如下:Linux 保持*nix格式,linux,bash,shell,vim,sh,Linux,Bash,Shell,Vim,Sh,我的代码可以工作,但不是我想要的方式。基本上,我的代码所做的就是查看当前目录,搜索文件夹,然后在这些文件夹中查看文件。如果其中一个文件扩展名是$Example变量的值,则它应删除具有相同起始文件名的所有其他文件,而不考虑扩展名,并将具有$Example扩展名的文件重命名为相同名称,而不使用$Example扩展名。代码如下: #!/bin/sh set -o errexit Example=dummy for d in *; do if test "$(ls -A "$d" 2>/d
#!/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
#/垃圾箱/垃圾箱
set-o errexit
示例=虚拟
对于d in*;做
如果测试“$(ls-A“$d”2>/dev/null)”;然后
如果[$(ls-1${d}/*.$Example 2>/dev/null | wc-l)-ge 1];然后
cd$(pwd)/$d;
例如*$中的f;做
fileName=“${f%.$Example}”;
mv“$f”“${f%.$Example}”;
#tr“\r”“\n”<“${f%.$Example}”>“${f%.$Example}”
listToDelete=$(查找名称“$fileName.*”);
对于g,以$listToDelete表示;做
rm$g;
完成;
完成;
光盘
fi;
fi;
完成
正在使用的文件是在VIM中创建的,因此应该使用Linux格式,而不是Windows格式。出于某种原因,一旦使用此代码剥离了扩展名,它将被格式化为
\r
,文件将无法运行。我在临时解决方案所在的位置添加了注释,但我想知道是否有某种方法可以更改mv
函数以保持Linux格式,或者是否有另一种方法来实现我想要的。谢谢这个答案并没有解决脚本源代码中可能出现的问题,而是提供了一种我认为用户希望实现的另一种方式:
#!/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"
此脚本执行以下操作:
$ 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
$bash-x script.sh
+ext=虚拟
++mktemp
+tmpfile=/tmp/tmp.9v5JMAcA12
+找到-类型f-名称'*.dummy'-execdir bash-x-c'cp“$3”“$2”&&
tee“${3%.$1}”*/dev/null'sh dummy/tmp/tmp.9v5JMAcA12'{}';'
+cp f1.dummy/tmp/tmp.9v5JMAcA12
+T形三通f1.bar f1.dummy f1.foo f1.txt
+cp f2.dummy/tmp/tmp.9v5JMAcA12
+三通f2.bar f2.dummy f2.foo f2.txt
+cp f3.dummy/tmp/tmp.9v5JMAcA12
+T形三通f3.bar f3.dummy f3.foo f3.txt
+rm-f/tmp/tmp.9v5JMAcA12
从调用bash
(以及从命令行上的bash
)中删除-x
,以禁用跟踪
我使用了
bash
而不是sh
,因为我的sh
不能正确地摸索${3%.$1}
正在使用的文件是在VIM中创建的,因此应该使用Linux格式,而不是Windows格式
这对正在使用的管线分离器没有影响
但我能想到三种不同的可能原因
ViM替换
\r
和\n
可能混淆了,或者Windows行分隔符(\r\n
)可能被错误地去除。如果您只是想在某个时候转换Windows行分隔符,请使用dos2unix
将它们转换为Unix行分隔文件,而不是sed
或vim
magic(如果可能),然后编辑它们。如果文件正在使用ViM添加或替换行分隔符,请记住,在ViM中,行分隔符是使用\n
搜索的,并替换为\r
,因为ViM只是将文件数据加载到缓冲区中。e、 g.%s/\n/somestring/
和%s/somestring/\r/g
Cygwin
如果您使用的是Cygwin,我敢肯定它默认为使用Windows行分隔符的ViM,但您可以将其更改为Unix行分隔符。但我不记得该怎么做了
ViM默认行分隔符
不确定如果您在GNU/Linux系统上,会发生什么情况,但是可以使用
:e++ff=Unix
mv
将ViM中使用的默认行分隔符指定给Unix,不应更改文件内容,无论您如何称呼它。您如何检查文件是否具有\r
而不是\n
?我无法在我的系统上重现此问题,我相信您的问题存在于其他地方。FWIW,\r
行结尾不是Windows格式,Windows将使用\r\n
。可能是您的脚本在某个地方有一个\r
,并将其放在文件名上。我不得不说,您的脚本对于它所做的事情来说相当复杂:用于$(find.-typef-name\*.${Example})中的文件;do root_name=${file%.$Example};mv$文件tmp$$;rm${root_name}*;mv tmp$$${root_name};完成
$ 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