在 Bash 中追加和重命名文件
Appending and Renaming File in Bash
我有一个文件
sandeep_mems_SJ_23102003.txt
需要重命名 sj_new_members_SJ_23102003.txt
我每天都会收到这些文件,所以 _SJ 之后的任何内容都保持不变至关重要。
到目前为止我得到了以下信息:-
for each in `/bin/ls -1`;do
sed -i 's/sandeep_mems_SJ/sj_new_members/g' $each ;
done
您可以使用 rename
实用工具:
rename 's/sandeep.*?_(\d+\.txt)$/sj_new_members_/' sandeep*txt
如果您要更改文件内容,sed
会对您有所帮助。要重命名文件本身,您可以这样做:
for each in *;do
mv $each sj_new_members_${each##sandeep_mems_SJ}
done
我使用 * 而不是 /bin/ls,因为它避免产生额外的进程并使用 Bash 的内置匹配(globbing)机制。
每个文件名都分配给 $each
。
mv
使用 Bash 的子字符串机制将 $each
重命名为 sj_new_members_
,后跟您想要的 $each
的子字符串。有关如何使用 Bash 子字符串的更多详细信息,请参见此处:
http://tldp.org/LDP/abs/html/string-manipulation.html
此外,这里还有一个使用 cut
命令的替代方法,它沿指定的字符定界符拆分,在本例中为 _
。我不太喜欢它,因为它会产生一个新进程,但它确实有效。查看 cut
手册页以获取更多详细信息。请注意,$(command)
等同于使用反引号——它在子 shell 中运行命令。
for each in *;do
mv $each sj_new_members_$(cut -d '_' -f 3- <<< $each)
done
for each in `/bin/ls -1`;do
mv $each sj_new_members_SJ${each##*SJ}
done
##*SJ
是参数扩展的语法,用于删除直到最后一个 SJ
的所有内容。还没有测试整个事情,但它应该工作。
我试图尽可能多地复制你的功能,所以这是一个实现 sed
:
的解决方案
for each in *; do
new=$(echo "$each" | sed 's/.*_SJ/sj_new_members_SJ_/')
mv $each $new
done
我认为您实际上不需要 ls -1
命令,因为 sed
会更改包含上述要求的那些文件的文件名。
本质上,我的命令所做的是将新文件名保存在变量中,new
,然后mv
将其重命名为保存在变量中的文件名。
我有一个文件
sandeep_mems_SJ_23102003.txt
需要重命名 sj_new_members_SJ_23102003.txt
我每天都会收到这些文件,所以 _SJ 之后的任何内容都保持不变至关重要。
到目前为止我得到了以下信息:-
for each in `/bin/ls -1`;do
sed -i 's/sandeep_mems_SJ/sj_new_members/g' $each ;
done
您可以使用 rename
实用工具:
rename 's/sandeep.*?_(\d+\.txt)$/sj_new_members_/' sandeep*txt
sed
会对您有所帮助。要重命名文件本身,您可以这样做:
for each in *;do
mv $each sj_new_members_${each##sandeep_mems_SJ}
done
我使用 * 而不是 /bin/ls,因为它避免产生额外的进程并使用 Bash 的内置匹配(globbing)机制。
每个文件名都分配给 $each
。
mv
使用 Bash 的子字符串机制将 $each
重命名为 sj_new_members_
,后跟您想要的 $each
的子字符串。有关如何使用 Bash 子字符串的更多详细信息,请参见此处:
http://tldp.org/LDP/abs/html/string-manipulation.html
此外,这里还有一个使用 cut
命令的替代方法,它沿指定的字符定界符拆分,在本例中为 _
。我不太喜欢它,因为它会产生一个新进程,但它确实有效。查看 cut
手册页以获取更多详细信息。请注意,$(command)
等同于使用反引号——它在子 shell 中运行命令。
for each in *;do
mv $each sj_new_members_$(cut -d '_' -f 3- <<< $each)
done
for each in `/bin/ls -1`;do
mv $each sj_new_members_SJ${each##*SJ}
done
##*SJ
是参数扩展的语法,用于删除直到最后一个 SJ
的所有内容。还没有测试整个事情,但它应该工作。
我试图尽可能多地复制你的功能,所以这是一个实现 sed
:
for each in *; do
new=$(echo "$each" | sed 's/.*_SJ/sj_new_members_SJ_/')
mv $each $new
done
我认为您实际上不需要 ls -1
命令,因为 sed
会更改包含上述要求的那些文件的文件名。
本质上,我的命令所做的是将新文件名保存在变量中,new
,然后mv
将其重命名为保存在变量中的文件名。