【shell基础】shell常用基础语句-替换后缀名复制同名文件
script
# copy images with same name as json file to one directory dir=/home/xxx/output_tfl_20220630 mkdir $dir/image for file in $dir/*.json; do # echo $file pngname=${file/%.json/.png} # OK
newname=${file%.json}.png # OK cp $pngname $dir/image # echo $pngname done
解析
脚本最重要的部分是
pngname=${file/%.json/.png}
这部分的含义就是将字符串file的.json后缀替换成.png,还有一种写法就是匹配删除,然后在大括号后面加上要替换成的部分,
newname=${file%.json}.png
如:${file%.json}.png,这个就是将字符串的.json后缀修改为.png。
两种方法都可以的。
注意,后来发现复制的文件有可能会发生变化,比如复制一张图像,原图像是正常的,1.5M大小,复制之后发现文件内容有损坏,大小是1.2M。
update 20220801
如果目录不一样,但是文件名需要一致呢?
basename: 该命令的作用是从路径中提取出文件名,使用方法为basename NAME [SUFFIX]
dirname: 该命令的作用是从路径中提取出目录名,使用方法为 dirname NAME
dir=/e/04_Dataset/traffic_light/annotation # mkdir $dir/image for file in $dir/tfl_anno/*.json; do echo $file dirn=$(dirname $file) base=$(basename $file) echo $dirn echo $base done
output:
/e/04_Dataset/traffic_light/annotation/tfl_anno/TFL_00010_20220726T132451.json /e/04_Dataset/traffic_light/annotation/tfl_anno TFL_00010_20220726T132451.json
update20220826
将imagedis文件中每一行的字符串images和png分别替换为labels、txt;script.sh内容如下:
#! bin/bash imagedis=/media/xxx/dataset/traffic_light/image_dis.txt labeldis=/media/xxx/dataset/traffic_light//label_dis.txt # lines=$(cat image) rm $labeldis for line in `cat $imagedis` do newname=${line%.png}.txt echo $newname # newname=${line/%images/labels} newname=${newname/images/labels} echo $newname echo $newname >>$labeldis # append # echo $newname > $labeldis # override done
出现错误
bad substitution
发现只要在运行的时候使用bash script.sh即可;
update20230117
替换后缀和路径,同时使用ffmpeg命令将yuv422yuyv格式转换为rgb24的png格式。
#! bin/bash dir=/media/xxx/dataset/traffic_light mkdir $dir/yuv2png yuv=testdata png=yuv2png for line in $dir/$yuv/*.yuv; do newname=${line%.yuv}.png echo $newname pngname=${newname/$yuv/$png} ffmpeg -s 1280*720 -pix_fmt yuyv422 -i $line -pix_fmt rgb24 $pngname done
运行
bash ./yuv2png.sh
update20230118
替换路径,将yuv422yuyv格式转为nv12格式,因为TDA4中app_tidl_od中的测试程序默认输入图像yuv格式是nv12,这样才能得到正确结果。
同时,将nv12格式的yuv文件的名称按序修改为占位为10个数字且高位补零;
#! bin/bash
# yuv2nv12.sh dir=/media/xxx/dataset/traffic_light yuv=testdata nv12=nv12 # yuv422yuyv to nv12 for line in $dir/$yuv/*.yuv; do newname=${line/$yuv/$nv12} ffmpeg -s 1280*720 -pix_fmt yuyv422 -i $line -pix_fmt nv12 $newname done # rename testlist=testlist mkdir $dir/$testlist n=0 for line in $dir/$nv12/*.yuv; do let n++ dirn=$(dirname $line) newname=$dirn/$(printf "%010d.yuv" $n) newname=${newname/$nv12/$testlist} cp $line $newname done
出现错误
let:not found
只要在运行的时候使用bash yuv2nv12.sh即可;
原因:/bin/sh 指向了 dash 而不是 bash , dash 不支持 let 命令;
update20230202
批量修改文件名,文件名添加前缀或者后缀;
类似于,文件名oldname.png,添加前缀改为new_oldname.png,添加后缀改为oldname_20230116.png;
# rename with prefix or suffix. dir=/media/01_dataset/traffic_light/tflvideo yuv2png=yuv2png png=png for file in $dir/$yuv2png/*.png; do echo $file dirn=$(dirname $file) base=$(basename $file) # prefix="new_"$base # newnamep=$dirn/$prefix # suffix=`echo $file|sed -r 's/(.*)(\..*)/\1_20230116\2/g'` suffix=`echo $base|sed -r 's/(.*)(\..*)/\1_20230116\2/g'` newnames=$dirn/$suffix # echo $prefix # echo $newnamep # echo $suffix # echo $newnames newname=${newnames/$yuv2png/$png} echo $newname cp $file $newname done
update20230214 指定多个目录循环查询执行

# yuyv2png dir=/media/01_dataset/traffic_light/tflvideo mkdir $dir/yuv2png # yuv=202302101 png=yuv2png # echo $png for files in 20230116 202302100 202302101 202302102 202302140 202302141; do # echo $files yuv=$files echo $yuv for file in $dir/$yuv/*.yuv; do echo $file # pngname=${file/%.json/.png} newname=${file%.yuv}.png # echo $newname pngname=${newname/$yuv/$png} # echo $pngname dirn=$(dirname $pngname) base=$(basename $pngname) prefix=$yuv"_"$base # echo $prefix # suffix=`echo $base|sed -r 's/(.*)(\..*)/\1_202302101\2/g'` addtime=$dirn/$prefix # echo $suffix echo $addtime # name=${addtime/$yuv/$png} # # cp $pngname $dir/image ffmpeg -s 1280*720 -pix_fmt yuyv422 -i $file -pix_fmt rgb24 $addtime done done
update20231205 间隔一定数目进行特定操作(取余)
script_path="$(pwd)" n=0 mkdir $script_path/filterdata # 间隔一定数目操作 for one in $script_path/badbehavior1/*.png; do let n++ ((tmp=$n %5)) if [ "$tmp" == 0 ]; then mv $one $script_path/filterdata fi done
取余操作:
#!/bin/bash for var in `seq 1 19`; do # echo $var ((tmp=$var %5)) if [ "$tmp" == 0 ]; then echo $var fi done
update20240423 获取某个目录下某种格式的文件的数量
# source /opt/vision_apps/vision_apps_init.sh dir=/home/root/dms for filename in testimg_fbb0 testimg_fbb1 testimg_fbb2 testimg_fbb3 testimg_fbb4 testimg_fcc0 testimg_fcc1 testimg_fcc2 testimg_fcc4; do echo $filename # name=$filename # echo $name rm -r testimg mkdir temp cnt=$(find "$dir/image/$filename/" -type f -name "*.png" | wc -l) mv $dir/image/$filename/*.png $dir/temp bash ./rename.sh rm -r output mkdir output
sed -i "s/num_frames 1000/num_frames $cnt/" dmsbhv/app_od_dmsbhv.cfg # ./vx_app_tidl_od_dmsbhv_c3imglist.out --cfg dmsbhv/app_od_dmsbhv.cfg > log_dmsbhv.txt done
关键语句
cnt=$(find "$dir/image/$filename/" -type f -name "*.png" | wc -l) #获取某目录中某类型文件的数量 sed -i "s/num_frames 1000/num_frames $cnt/" dmsbhv/app_od_dmsbhv23183.cfg #修改配置文件中某参数
sed
命令使用-i
选项直接修改文件内容,注意,sed
命令的替换操作是全局的。
1 | s /num_frames 1000 /num_frames $cnt/ # 这是一个替换操作,$cnt是脚本接收的参数。 |
20240430 删除前导零,获取文件某行内容

root=/c/test0p6 imgfalse=img_false imgmiss=img_miss testfalse=test_false testmiss=test_miss imgroot=/d/TDA4/JKL/bad23183/driverdata/retain txtdir=_txtfile # 1. 根据false目录中每个子目录的每个文件名称,获取名称中的数字, # 2. 在txt文件中对应的数字行得到原图像名称,复制图像 cd $root/$testfalse n=0 for dir in `ls .`; do echo "dir= $dir" dirn="${dir//false_/}" # echo "dirn= $dirn" filename=${dirn}.txt txtfile=$imgroot/$txtdir/$filename # echo "txtfile= $txtfile" if [ $n -gt 1 ]; then break fi for file in $root/$testfalse/$dir/*.png; do base=$(basename $file) # dmsbhv_0000000809.png # echo "base= $base" strk=$base temp="${strk//dmsbhv_/}" temp="${temp//.png/}" k=$(echo "$temp" | sed 's/^0*//') # delete前导零 # echo "k= $k" # imgname=$(awk "NR==${k}" $txtfile) # OK获取文件某行内容 imgname=$(sed -n "${k}p" $txtfile) # OK获取文件某行内容 # echo "imgname= $imgname" temp=testimg_ imgdir="$temp$dirn" # echo "imgdir= $imgdir" # echo "src= $imgroot/$imgdir/$imgname" # echo "dst= $root/$imgfalse" cp $imgroot/$imgdir/$imgname $root/$imgfalse done let n++ done
关键语句
temp="0000000809" txtfile=aaa.txt k=$(echo "$temp" | sed 's/^0*//') # delete前导零 # imgname=$(awk "NR==${k}" $txtfile) # OK获取文件某行内容 imgname=$(sed -n "${k}p" $txtfile) # OK获取文件某行内容 n=0 if [ $n -gt 1 ]; then break fi
再有注意字符串替换、if语句以及添加前缀、后缀;
-gt:大于,greater than -eq:等于,equal -lt:小于,less than -ge:大于等于,greater than or equal -le:小于等于,less than or equal -ne:不等于,not equal
注意break和continue的用法;
update20250225
多层循环遍历某些目录
#!/bin/bash dirs_img=" /media/uuu/485E234682AE9EFD/01_dataset/APA/anno_image/data/sss/yuyan_multitask_batch4_1968_20241031_img /media/uuu/485E234682AE9EFD/01_dataset/APA/anno_image/data/sss/yuyan_multitask_batch5_4053_20241105_6_img /media/uuu/485E234682AE9EFD/01_dataset/APA/anno_image/data/sss/yuyan_multitask_batch5_4053_20241105_7_img /media/uuu/485E234682AE9EFD/01_dataset/APA/anno_image/data/sss/yuyan_multitask_batch6_2136_20241107_4_img /media/uuu/485E234682AE9EFD/01_dataset/APA/anno_image/data/sss/yuyan_multitask_batch7_1316_20241114_1_img /media/uuu/485E234682AE9EFD/01_dataset/APA/anno_image/data/sss/yuyan_multitask_batch7_1316_20241114_2_img /media/uuu/485E234682AE9EFD/01_dataset/APA/anno_image/data/sss/yuyan_multitask_batch8_2000_20241202_5_img " for dir in $dirs_img; do echo $dir for file in $dir/*.png; do # echo $file # 检查是否是文件 if [[ -f $file ]]; then # 重命名文件,添加后缀 # mv "$file" "${file}${suffix}" suffix=`echo $file|sed -r 's/(.*)(\..*)/\1_leftImg8bit\2/g'` # suffix=`echo $file|sed -r 's/(.*)(\..*)/\1_gtFine_labelIds\2/g'` # suffix=`echo $file|sed -r 's/(.*)(\..*)/\1_gtFine_labelIds\2/g'` mv $file $suffix fi done done
主要关注在遍历某些指定目录。
参考
1. shell获取文件名和文件目录;
完
心正意诚,做自己该做的事情,做自己喜欢做的事情,安静做一枚有思想的技术媛。
版权声明,转载请注明出处:https://www.cnblogs.com/happyamyhope/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】