通过比较两个文件夹bash/sed中的filename来重命名文件

通过比较两个文件夹bash/sed中的filename来重命名文件,bash,sed,Bash,Sed,我在和bash玩我被一个问题绊住了 在第一个文件夹中,我有一个文件列表 folder1/first_1.txt folder1/second_2.txt folder1/third_3.txt folder1/फाइल_3.txt folder2/1.txt folder2/2.txt folder2/3.txt 在第二个文件夹中,我有一个文件列表 folder1/first_1.txt folder1/second_2.txt folder1/third_3.txt folder1/फाइ

我在和bash玩我被一个问题绊住了

在第一个文件夹中,我有一个文件列表

folder1/first_1.txt
folder1/second_2.txt
folder1/third_3.txt
folder1/फाइल_3.txt
folder2/1.txt
folder2/2.txt
folder2/3.txt
在第二个文件夹中,我有一个文件列表

folder1/first_1.txt
folder1/second_2.txt
folder1/third_3.txt
folder1/फाइल_3.txt
folder2/1.txt
folder2/2.txt
folder2/3.txt
现在,我需要比较第一个文件夹和第二个文件夹的文件名,并将第二个文件夹的文件名替换为第一个文件夹的文件名

ouputfolder/fist.text
ouputfolder/second.text
ouputfolder/third.text
ouputfolder/फाइल.text

如何使用bash/sed实现这一点?如有任何建议,我们将不胜感激

使用
find
查找
folder1
中的文件,使用
while
循环检查
folder2
文件名中每个文件名的相关部分是否存在。如果存在,则进行必要的重命名:

find folder1 -maxdepth 1 -type f -name '*.txt' -print0 | \
  while IFS= read -d $'\0' -r file; do start="${file%%_*}"; end="${file#*_}"; \
   [ -f folder2/"$end" ] && echo mv -i folder2/"$end" folder2/"$start".text; done
对将要进行的更改感到满意吗?如果正常,则移除回声,让操作进行:

find folder1 -maxdepth 1 -type f -name '*.txt' -print0 | \
   while IFS= read -d $'\0' -r file; do start="${file%%_*}"; end="${file#*_}"; \
     [ -f folder2/"$end" ] && mv -i folder2/"$end" folder2/"$start".text; done
示例:

% tree
.
├── folder1
│   ├── first_1.txt
│   ├── second_2.txt
│   └── third_3.txt
└── folder2
    ├── 1.txt
    ├── 2.txt
    └── 3.txt


% find folder1 -maxdepth 1 -type f -name '*.txt' -print0 | while IFS= read -d $'\0' -r file; do start="${file%%_*}"; end="${file#*_}"; [ -f folder2/"$end" ] && echo mv -i folder2/"$end" folder2/"$start".text; done
mv -i folder2/2.txt folder2/second.text
mv -i folder2/3.txt folder2/third.text
mv -i folder2/1.txt folder2/first.text

% find folder1 -maxdepth 1 -type f -name '*.txt' -print0 | while IFS= read -d $'\0' -r file; do start="${file%%_*}"; end="${file#*_}"; [ -f folder2/"$end" ] && mv -i folder2/"$end" folder2/"$start".text; done 

% tree                                                  
.
├── folder1
│   ├── first_1.txt
│   ├── second_2.txt
│   └── third_3.txt
└── folder2
    ├── first.text
    ├── second.text
    └── third.text

进行编辑以使所有文件名都能正常工作

sed可用于搜索和替换文件中的字符串。它不自然地用于文件名

尝试此测试版本(也使用shellcheck进行检查):

生成测试文件夹:

mkdir folder1
printf "f1 %s\n" "one" > folder1/first_1.txt
printf "f1 %s\n" "two" > folder1/second_2.txt
printf "f1 %s\n" "three" > folder1/third_3.txt
printf "f1 %s\n" "four" > folder1/"$(printf "\0\1\2\3\4\5\6\7\10\11\12\13\14\15\16\17\20\21\22\23\24\25\26\27\30\31\32\33\34\35\36\37\40\42\47\54\77\134\140\177")"_4.txt
mkdir folder2
printf "f2 %s\n" "one" > folder2/1.txt
printf "f2 %s\n" "two" > folder2/2.txt
printf "f2 %s\n" "three" > folder2/3.txt
printf "f2 %s\n" "four" > folder2/4.txt
列出测试元素:

ls -1b folder*/*.txt

folder1/\001\002\003\004\005\006\a\b\t\n\v\f\r\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\ "',?\\`\177_4.txt
folder1/first_1.txt
folder1/second_2.txt
folder1/third_3.txt
folder2/1.txt
folder2/2.txt
folder2/3.txt
folder2/4.txt
运行脚本:

./newscript.sh 
显示新文件并检查结果:

ls -1b folder2/*.text

folder2/\001\002\003\004\005\006\a\b\t\n\v\f\r\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\ "',?\\`\177.text
folder2/first.text
folder2/second.text
folder2/third.text
备选单行版本 我觉得这很有趣:) 它也已经过测试,并通过shellcheck进行了验证

find folder2 -name \*.txt -printf "%f\0" | xargs -0 -I xxxx bash -c '( folder1fn=$(find folder1 -name \*_xxxx -printf "%f") ; mv folder2/xxxx folder2/"${folder1fn%_xxxx}".text )'

您是否还希望将
folder2
文件的内容复制到
outputFolder
中?是的,我想这很好。文件名中的unicode字符作为फाइल.txt??我认为这个脚本不会正常工作???@Drudge对我来说很好。如果出现问题,请检查您的
locale
应该是什么语言环境??我很困惑。我也有同样的伴侣:(.现在我要发疯了,当我使用你的解决方案时,它既不工作也不显示错误。所以,我认为这是unicode的问题。不要使用
ls
输出任何东西。
ls
是一个交互式查看目录元数据的工具。任何试图用代码解析
ls
输出的尝试都会失败。Globs更多简单而正确:
对于*.txt中的文件
。读真!我假设(不写它)所有文件名只包含[0-9a-zA-Z.]个字符,请参阅问题及其文件名示例。好的,第二个版本的特殊字符证明将在一天结束时发布(法国阿尔卑斯山)@RanyAlbegWein:已提供不带ls的新版本。@Drudge它已通过测试,文件名怪异,脚本已通过shellcheck验证。请尝试此版本。