如何使用bash和sed操作文件名?
我正在尝试循环浏览目录中的所有文件 我想对每个文件做一些工作(将其转换为xml,不包括在示例中),然后将文件写入新的目录结构如何使用bash和sed操作文件名?,bash,shell,sed,Bash,Shell,Sed,我正在尝试循环浏览目录中的所有文件 我想对每个文件做一些工作(将其转换为xml,不包括在示例中),然后将文件写入新的目录结构 for file in `find /home/devel/stuff/static/ -iname "*.pdf"`; do echo $file; sed -e 's/static/changethis/' $file > newfile +".xml"; echo $newfile; done 我希望结果是: $file=>/home/devel
for file in `find /home/devel/stuff/static/ -iname "*.pdf"`;
do
echo $file;
sed -e 's/static/changethis/' $file > newfile +".xml";
echo $newfile;
done
我希望结果是:
$file=>/home/devel/stuff/static/2002/hello.txt
$newfile=>/home/devel/stuff/changethis/2002/hello.txt.xml
如何更改我的
sed
行?是否要更改文件名?然后
for file in /home/devel/stuff/static/*/*.txt
do
echo "Moving $file"
mv "$file" "${file/static/changethis}.xml"
done
在使用脚本之前,请确保
/home/devel/stuff/static/*/*.txt
是您想要的。如果您需要重命名多个文件,我建议使用重命名
命令:
# remove "-n" after you verify it is what you need
rename -n 's/hello/hi/g' $(find /home/devel/stuff/static/ -type f)
或者,如果您没有重命名
,请尝试以下操作:
find /home/devel/stuff/static/ -type f | while read FILE
do
# modify line below to do what you need, then remove leading "echo"
echo mv $FILE $(echo $FILE | sed 's/hello/hi/g')
done
首先,必须根据初始文件的名称创建新文件的名称。显而易见的解决办法是:
newfile=${file/static/changethis}.xml
其次,您必须确保新目录存在,如果不存在,则创建新目录:
mkdir -p $(dirname $newfile)
然后,您可以对文件执行以下操作:
doSomething < $file > $newfile
doSomething<$file>$newfile
我不会执行for
循环,因为可能会使命令行过载。命令行的长度是有限的,如果您重载它,它只会在不给您任何警告的情况下删除多余的命令行。如果您的查找返回100个文件,它可能会起作用。如果它返回1000个文件,它可能会工作,但如果您的查找返回1000个文件,并且您永远不会知道,它可能会失败
处理此问题的最佳方法是将find作为管道传输到while read语句中
sed命令仅适用于STDIN和文件,但不适用于文件名,因此,如果您想使用文件名,必须执行以下操作:
$newname="$(echo $oldname | sed 's/old/new/')"
find /home/devel/stuff/static/ -name "*.pdf" | while read $file
do
echo $file;
newfile="$(echo $file | sed -e 's/static/changethis/')"
newfile="$newfile.xml"
echo $newfile;
done
以获取文件的新名称。$()
构造执行命令并将命令的结果放在STDOUT上
因此,您的脚本将如下所示:
$newname="$(echo $oldname | sed 's/old/new/')"
find /home/devel/stuff/static/ -name "*.pdf" | while read $file
do
echo $file;
newfile="$(echo $file | sed -e 's/static/changethis/')"
newfile="$newfile.xml"
echo $newfile;
done
现在,由于要重命名文件目录,因此在移动或复制之前,必须确保该目录存在:
find /home/devel/stuff/static/ -name "*.pdf" | while read $file
do
echo $file;
newfile="$(echo $file | sed -e 's/static/changethis/')"
newfile="$newfile.xml"
echo $newfile;
#Check for directory and create it if it doesn't exist
$dirname=$(dirname "$newfile")
if [ ! -d "$dirname" ]
then
mkdir -p "$dirname"
fi
#Directory now exists, so you can do the move
mv "$file" "$newfile"
done
注意引号以处理文件名中有空格的情况
顺便说一下,不要这样做:
if [ ! -d "$dirname" ]
then
mkdir -p "$dirname"
fi
您可以这样做:
[ -d "$dirname"] || mkdir -p "$dirname"
|
表示仅当测试不正确时才执行以下命令。因此,如果[-d“$dirname”]是错误的语句(目录不存在),则运行mkdir
当您看到shell脚本时,这是一个相当常见的快捷方式
OUTPUT="$(pwd)";
for file in `find . -iname "*.pdf"`;
do
echo $file;
cp $file $file.xml
echo "file created in directory = {$OUTPUT}"
done
这将创建一个名为whatyourfilename.xml的新文件,对于hello.pdf,创建的新文件将是hello.pdf.xml,基本上它将创建一个新文件,并在末尾附加.xml
请记住,上面的脚本在目录/home/devel/stuff/static/
中查找文件,其文件名与find命令的matcher字符串匹配(在本例中为*.pdf),并将其复制到当前的工作目录
此特定脚本中的find命令仅查找文件名以.pdf结尾的文件。如果要对文件名以.txt结尾的文件运行此脚本,则需要将find命令更改为
find/home/devel/stuff/static/-iname“*.txt”
,否。我正在尝试获取文件名,追加“.xml”把它放在一个不同的地方directory@Mu乔:您的通配符扩展将丢失静态目录中的任何.txt文件。“查找”命令将不起作用。@Hai Vu,是的,没错。但我不知道op在静态目录中是否有任何txt文件。这就是我让他确认路径是否正确的部分原因。