首页 > 解决方案 > 在bash中使用for循环创建目录

问题描述

我有这些文件。假设每个“测试”代表一个服务器的名称:

test10.txt
test11.txt
test12.txt
test13.txt
test14.txt
test15.txt
test16.txt
test17.txt
test18.txt
test19.txt
test1.txt
test20.txt
test21.txt
test22.txt
test23.txt
test24.txt
test25.txt
test26.txt
test27.txt
test28.txt
test29.txt
test2.txt
test30.txt
test31.txt
test32.txt
test33.txt
test34.txt
test35.txt
test36.txt
test37.txt
test38.txt
test39.txt
test3.txt
test40.txt
test4.txt
test5.txt
test6.txt
test7.txt
test8.txt
test9.txt

在每个 txt 文件中,我都有这种类型的数据:

2019-10-14-00-00;/dev/hd1;1024.00;136.37;/
2019-10-14-00-00;/dev/hd2;5248.00;4230.53;/usr
2019-10-14-00-00;/dev/hd3;2560.00;481.66;/var
2019-10-14-00-00;/dev/hd4;3584.00;67.65;/tmp
2019-10-14-00-00;/dev/hd5;256.00;26.13;/home
2019-10-14-00-00;/dev/hd1;1024.00;476.04;/opt
2019-10-14-00-00;/dev/hd5;384.00;0.38;/usr/xxx
2019-10-14-00-00;/dev/hd4;256.00;21.39;/xxx
2019-10-14-00-00;/dev/hd2;512.00;216.84;/opt
2019-10-14-00-00;/dev/hd3;128.00;21.46;/var/
2019-10-14-00-00;/dev/hd8;256.00;75.21;/usr/
2019-10-14-00-00;/dev/hd7;384.00;186.87;/var/
2019-10-14-00-00;/dev/hd6;256.00;0.63;/var/
2019-10-14-00-00;/dev/hd1;128.00;0.37;/admin
2019-10-14-00-00;/dev/hd4;256.00;179.14;/opt/
2019-10-14-00-00;/dev/hd3;2176.00;492.93;/opt/
2019-10-14-00-00;/dev/hd1;256.00;114.83;/opt/
2019-10-14-00-00;/dev/hd9;256.00;41.73;/var/
2019-10-14-00-00;/dev/hd1;3200.00;954.28;/var/
2019-10-14-00-00;/dev/hd10;256.00;0.93;/var/
2019-10-14-00-00;/dev/hd10;64.00;1.33;/
2019-10-14-00-00;/dev/hd2;1664.00;501.64;/opt/
2019-10-14-00-00;/dev/hd4;256.00;112.32;/opt/
2019-10-14-00-00;/dev/hd9;2176.00;1223.1;/opt/
2019-10-14-00-00;/dev/hd11;22784.00;12325.8;/opt/
2019-10-14-00-00;/dev/hd12;256.00;2.36;/
2019-10-14-06-00;/dev/hd12;1024.00;137.18;/
2019-10-14-06-00;/dev/hd1;256.00;2.36;/
2019-10-14-00-00;/dev/hd1;1024.00;136.37;/
2019-10-14-00-00;/dev/hd2;5248.00;4230.53;/usr
2019-10-14-00-00;/dev/hd3;2560.00;481.66;/var
2019-10-14-00-00;/dev/hd4;3584.00;67.65;/tmp
2019-10-14-00-00;/dev/hd5;256.00;26.13;/home
2019-10-14-00-00;/dev/hd1;1024.00;476.04;/opt
2019-10-14-00-00;/dev/hd5;384.00;0.38;/usr/xxx
2019-10-14-00-00;/dev/hd4;256.00;21.39;/xxx
2019-10-14-00-00;/dev/hd2;512.00;216.84;/opt
2019-10-14-00-00;/dev/hd3;128.00;21.46;/var/
2019-10-14-00-00;/dev/hd8;256.00;75.21;/usr/
2019-10-14-00-00;/dev/hd7;384.00;186.87;/var/
2019-10-14-00-00;/dev/hd6;256.00;0.63;/var/
2019-10-14-00-00;/dev/hd1;128.00;0.37;/admin
2019-10-14-00-00;/dev/hd4;256.00;179.14;/opt/
2019-10-14-00-00;/dev/hd3;2176.00;492.93;/opt/
2019-10-14-00-00;/dev/hd1;256.00;114.83;/opt/
2019-10-14-00-00;/dev/hd9;256.00;41.73;/var/
2019-10-14-00-00;/dev/hd1;3200.00;954.28;/var/
2019-10-14-00-00;/dev/hd10;256.00;0.93;/var/
2019-10-14-00-00;/dev/hd10;64.00;1.33;/
2019-10-14-00-00;/dev/hd2;1664.00;501.64;/opt/
2019-10-14-00-00;/dev/hd4;256.00;112.32;/opt/

我想为每个服务器创建一个目录,在每个目录中为每个 FS 创建一个 txt 文件,并在这些 txt 文件中放入与 FS 对应的每一行。

为此,我尝试了循环:

#!/bin/bash

directory=(ls *.txt | cut -d'.' -f1)
for d in $directory
do
        if [ ! -d $d ]
        then
                mkdir $d
        fi
done

for i in $(cat *.txt)
do
        file=$(echo $i | awk -F';' '{print $2}' | sort | uniq | cut -d'/' -f3 )
        data=$(echo $i | awk -F';' '{print $2}' )
        echo $i | grep -w $data >> /xx/xx/xx/xx/xx/${directory/${file}.txt
done

但是这个循环不能正常工作。创建目录但不是每个目录中的文件。

我想要类似的东西:

test1/hd1.txt(每行对应 hd1.txt 中的 hd1 fs)

每个服务器都一样。

你能告诉我怎么做吗?

标签: linuxbash

解决方案


#!/bin/bash

for src in *.txt; do
    # start a subshell so we don't need to cd back afterwards
    # make "$src" be stdin before cd, so we don't need full path
    # be careful that in subshell only awk reads from stdin
    (
        # extract server name to use as directory
        dir=/xx/xx/xx/xx/xx/"${src%.txt}"

        # chain with "&&" so failures don't cause bad files
        mkdir -p "$dir" &&
        cd "$dir" &&
        awk -F \; '{ split($2, dev, "/"); print > dev[3]".txt" }'
    ) < "$src"
done
  • awk 脚本读取由分号分隔的行。
  • 它拆分斜杠上的第二个字段以提取设备名称(假设设备始终具有以下形式:/dev/名称
  • 最后,>将输出发送到相关文件。

作为参考,您可以通过执行使您的脚本工作directory=$(...);添加前缀mkdir(假设前缀目录已经存在);关闭参考${directory};并引用所有变量引用以确保安全:

#!/bin/bash

directory=$(ls *.txt | cut -d'.' -f1)
for d in "$directory"
do
        if [ ! -d "$d" ]
        then
                mkdir /xx/xx/xx/xx/xx/"$d"
        fi
done

for i in $(cat *.txt)
do
        file=$(echo "$i" | awk -F';' '{print $2}' | sort | uniq | cut -d'/' -f3 )
        data=$(echo $i | awk -F';' '{print $2}' )
        echo "$i" | grep -w "$data" >> /xx/xx/xx/xx/xx/"${directory}"/"${file}".txt
done

推荐阅读