Linux Bash循环-为目录中的每个现有txt文件创建一个文件夹
我想组织目录中的文本文件。我试图通过bash为每个文件创建一个目录来实现这一点。当我将文件移动到其各自的新文件夹时,我想修改原始的Linux Bash循环-为目录中的每个现有txt文件创建一个文件夹,linux,bash,shell,unix,Linux,Bash,Shell,Unix,我想组织目录中的文本文件。我试图通过bash为每个文件创建一个目录来实现这一点。当我将文件移动到其各自的新文件夹时,我想修改原始的文件名,并创建一个包含原始文件名的附加文本文件labeldinfo.txt(此文件也放在新文件夹中)。文件名更改从xxx-file\u name-aa1.txt更改为xxx-aa1.txt。第一个和最后一个-之间的任何内容都将被删除。该文件夹与文件xxx-aa1同名 test.sh(my sed语句)删除空格并将所有内容转换为小写,但最后一个- FILE_PATH="
文件名
,并创建一个包含原始文件名的附加文本文件labeldinfo.txt
(此文件也放在新文件夹中)。文件名更改从xxx-file\u name-aa1.txt
更改为xxx-aa1.txt
。第一个和最后一个-
之间的任何内容都将被删除。该文件夹与文件xxx-aa1
同名
test.sh(my sed语句)删除空格并将所有内容转换为小写,但最后一个-
FILE_PATH="/media/sf_linux_sandbox/txt_files/"
while read -r file; do
#sed statement empty
new_name=$(echo "$file" | sed 's/^\(.*\)\(-[^-]*\)$/\L\1\E\2/; s/ *- */-/; s/^\(.*\) \+- *\([^-]*\)$/\1-\2/; s/ /_/g')
mv "$file" "$new_name"
done < <(find $FILE_PATH -maxdepth 1 -type f -name '*.txt')
期望输出:
|-- ./
| |-- xxxx-aa1
| |--xxx-aa1.txt
| |--info.txt // contains name 'test_file1'
| |-- xxxx-bb2
|--xxx-bb2.txt
|--info.txt // contains name 'test_file2'
电流输出
|-- ./
| |-- xxxx-test_file-aa1
| |--xxxx-test_file-aa1.txt
| |-- xxxx-test_file-bb2
|--xxxx-test_file-bb2.txt
将
sed
更改为
new_name=$(echo "$file" | sed -r 's/-[^-]*-/-/g')
例如:
-[^-]*-
选择两个-
之间的字符串,seds
将其替换为-
FILE_PATH="/media/sf_linux_sandbox/txt_files/"
while read -r file; do
#sed statement empty
new_name=$(echo "$file" | sed 's/^\(.*\)\(-[^-]*\)$/\L\1\E\2/; s/ *- */-/; s/^\(.*\) \+- *\([^-]*\)$/\1-\2/; s/ /_/g')
mv "$file" "$new_name"
done < <(find $FILE_PATH -maxdepth 1 -type f -name '*.txt')
您还可以使用grep
命令获取目录名
$ echo $new_name | grep -o '^[^.]*'
xxxx-aa1
^[^.]*
选择文件名中不包含扩展名的部分
编辑
获取文件名
$ echo "xxx-test_file-aa1.txt" | grep -oP '(?<=-)[^.]*(?=-)'
test_file
$echo“xxx-test_file-aa1.txt”|grep-oP'(?您实际上可以在Bash本身中执行所有这些操作
由于您有-maxdepth 1
,看起来您可以使用通配符循环而不是find
,所以我也对其进行了重构
FILE_PATH="/media/sf_linux_sandbox/videos/"
for file in "$FILE_PATH"/*.mp4; do
tmp=${file#*-}; head=${file%-"$tmp"}
mid=${tmp%-*}; tail=${tmp#"$mid"-}
base="${head,,}-${tail,,}"
dir=${base%.mp4}
mkdir -p "$dir"
mv "$file" "$dir/$base"
echo "$mid" >"$dir"/info.txt
done
简单地说,${var#prefix}
扩展到var
的值,并删除前缀
,${var%suffix}
相应地用后缀执行相同的替换。最后,${var,,}
生成值的小写版本。然后,我们只需从这些部分组合您想要的文件名结构。太好了!离我的目标更近了。我如何能够将介于-
之间的内容输出到txt文件。例如xxxx-test\u file-aa1.txt
获取test\u file\u aa1
并输出到中的fo.txt
对不起,我打错了,只是想抓住-
和最后一个-
之间的内容,所以它就是test\u文件
。如果文件有两个以上的-
像这样xxxx-test\u文件1-aa1
到test\u文件1
应该是xxxx-test\u文件1-aa1
吗问题?我已经在回答中更正了。假设xxxx-test\u文件1-aa1
是文件名,而不是xxxx-test\u文件1-aa1
,正如您之前的评论。如果编辑错误,请指出:)您的测试用例根本不涉及小写功能。此外,您有新的\u名称
,但随后移动到新的\u文件
。最后,您的查找
循环有.mp4
文件,但您的伪示例显示了.txt
文件。@triplee,很抱歉我也用mp4文件进行了测试,忘了恢复我的pseu为txt文件编写所有代码。非常清楚,已测试过,但如果文件名中有多个连字符-
,则会中断。例如xxxx-test\u file-1-aa1
不会转换为xxxx-aa1
,而是xxxx-1
。对于新文件夹/文件名而言,唯一重要的是第一个-之前的内容e> 最后一个-
.重构后的文件名可以使用任意数量的破折号(但如果破折号少于两个,则会不稳定)。作为历史参考,早期版本使用了IFS=-
和set
来分割文件名,但是硬编码正好是两个破折号。哦,不知道IFS=-
和set
正好是两个破折号。现在一切都有意义了。很好地解释了!这并不是说它们不能工作,而是重构让它成功了通过切换到前缀/后缀,代码变得更简单。好的,运行得很好,正如预期的那样。我对文件的名称格式不是很具体,现在我发现具有这种类型名称的文件有一个问题xxxx-test\u file-caa-v3u
(结尾处有两个以上的-
)。我做了一个
FILE_PATH="/media/sf_linux_sandbox/videos/"
for file in "$FILE_PATH"/*.mp4; do
tmp=${file#*-}; head=${file%-"$tmp"}
mid=${tmp%-*}; tail=${tmp#"$mid"-}
base="${head,,}-${tail,,}"
dir=${base%.mp4}
mkdir -p "$dir"
mv "$file" "$dir/$base"
echo "$mid" >"$dir"/info.txt
done