![使用 awk 将文件按名称分组并移动到各自的目录](https://linux22.com/image/160467/%E4%BD%BF%E7%94%A8%20awk%20%E5%B0%86%E6%96%87%E4%BB%B6%E6%8C%89%E5%90%8D%E7%A7%B0%E5%88%86%E7%BB%84%E5%B9%B6%E7%A7%BB%E5%8A%A8%E5%88%B0%E5%90%84%E8%87%AA%E7%9A%84%E7%9B%AE%E5%BD%95.png)
我试图根据名称(_ 之前的前几个字母)对文件进行分组,并使用 awk 将它们移动到单独的目录(如果不存在则创建新目录)。
可以使用命令创建测试数据:
echo "1" > 123_20190911_110011.txt
echo "2" > 123_20190911_110012.txt
echo "0" > 123_20190910_110010.txt
echo "1" > 1234_20190911_110011.txt
echo "2" > 1234_20190911_110012.txt
echo "0" > 1234_20190910_110010.txt
ls -ltr 的输出是:
-rw-r--r-- 1 vipin vipin 2 Sep 11 23:17 123_20190911_110011.txt
-rw-r--r-- 1 vipin vipin 2 Sep 11 23:17 123_20190911_110012.txt
-rw-r--r-- 1 vipin vipin 2 Sep 11 23:17 123_20190910_110010.txt
-rw-r--r-- 1 vipin vipin 2 Sep 11 23:17 1234_20190911_110011.txt
-rw-r--r-- 1 vipin vipin 2 Sep 11 23:17 1234_20190911_110012.txt
-rw-r--r-- 1 vipin vipin 2 Sep 11 23:17 1234_20190910_110010.txt
在这种情况下,我期望 2 个目录 123 和 1234 以及文件移动到如下目录中:
Dir 123 has files
123_20190911_110011.txt
123_20190911_110012.txt
123_20190910_110010.txt
Dir 1234 has files
1234_20190911_110011.txt
1234_20190911_110012.txt
1234_20190910_110010.txt
下面的代码不起作用。甚至没有创建目录,也没有显示任何错误。
for i in `ls -p | grep -v /` ## to list only files
do
echo $i | awk -F'_' '{mkdir -p $1; cp $i $1}'
done
能够使用以下命令创建目录,但如何在其中添加移动命令?
for i in `ls -p | grep -v / `; do echo $i | awk -F'_' '{print $1; dir= $1}' | xargs mkdir -p ; done
答案1
你不应该在里面做mv
或做。以下作品:cp
awk
for i in * ; do
[ -f "$i" ] || continue
dir_name="$(echo $i | awk -F'_' '{print $1}')"
mkdir -p -- "$dir_name"
cp -- "$i" "$dir_name"
done
awk
但是,您可以使用%
bash 中的运算符来删除第一个下划线之后的所有内容,以获取目录名称,而不是。
for i in * ; do
[ -f "$i" ] || continue
dir_name="${i%%_*}"
mkdir -p -- "$dir_name"
cp -- "$i" "$dir_name"
done
(如果你想移动,请使用mv
代替)cp
答案2
将所有文件名放入示例文件中并按照以下步骤操作
#step1 it creates directory
awk -F "_" '{print $1}' samplefile | awk '{if (!seen [$1]++)print "mkdir" " " $0}'| sh
#step2: moves file to respective directory
for i in `awk -F "_" '{print $1}' samplefile | sort -u` ; do sed -n '/^'$i'_/p' samplefile | awk -v i="$i" '{print "mv" " " $1 " " i}'|sh ; done