Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 如何使用bash将未知数量的源文件名拆分为指定数量的输出文件_Linux_Bash_Shell_Scripting_Sh - Fatal编程技术网

Linux 如何使用bash将未知数量的源文件名拆分为指定数量的输出文件

Linux 如何使用bash将未知数量的源文件名拆分为指定数量的输出文件,linux,bash,shell,scripting,sh,Linux,Bash,Shell,Scripting,Sh,我正在尝试用BASH编写一个脚本,该脚本将读取源目录中的所有文件名,该目录具有未知的文件计数,然后在指定数量的输出文件之间尽可能平均地分割这些文件名。用户输入是源目录、目标目录和目标文件计数 例如,假设在一个源目录中有10个文件,用户指定要将这些文件的名称拆分为3个输出文件 源文件名: test test2 test3 test4 test5 test6 test7 test8 test9 测试 测试2 测试3 测试4 测试5 测试6 测试7 测试8 测试9 结果文件: FILE1 test t

我正在尝试用BASH编写一个脚本,该脚本将读取源目录中的所有文件名,该目录具有未知的文件计数,然后在指定数量的输出文件之间尽可能平均地分割这些文件名。用户输入是源目录、目标目录和目标文件计数

例如,假设在一个源目录中有10个文件,用户指定要将这些文件的名称拆分为3个输出文件

源文件名:

test test2 test3 test4 test5 test6 test7 test8 test9 测试 测试2 测试3 测试4 测试5 测试6 测试7 测试8 测试9 结果文件:

FILE1 test test2 test3 test4 文件1 测试 测试2 测试3 测试4 (有4个)

文件2 测试5 测试6 测试7 (有3个)

文件3 测试8 测试9 测试10 (有3个)

到目前为止,我已经提出了以下方法,它将始终捕获所有文件,因为我正在强制进行“汇总”,但不会在所有情况下提供所需的输出文件数,因为它不会导致输出文件中文件名的数量不均

ls -l -d -1 $source/{*,.*} | tail -n +3 |  awk '{printf "%s\n",$9}' > hdpLoadList
fileCount=`ls -1 $source | wc -l`
threadCount=$3 

fptf=$(bc <<< "scale=1;($fileCount/$threadCount)+.9")
fptf=${fptf:0:1}

sPos=1
sLen=$fptf
for i in `seq 1 $threadCount`;
 do
   sed -n ${sPos},${sLen}p hdpLoadList | sed -e ':a;N;$!ba;s/\n/ /g' > hdpLoadP_$i
   sPos=$(($sPos+$fptf))
   sLen=$(($sLen+$fptf))
 done
ls-l-d-1$source/{*,.*}tail-n+3 | awk'{printf“%s\n”,$9}>hdpLoadList
fileCount=`ls-1$source | wc-l`
threadCount=$3

fptf=$(bc脚本,比如说
split

#!/bin/bash

# Create an array with all the files
myArray=("$1"/*)

# Get array length
arrayLength=${#myArray[@]}

# Divide length by the third arg value
divRes=$(( $arrayLength / $3 ))

# Iterate through array using a counter
for ((i=0; i<${#myArray[@]}; i++)); do
    count=$(( $i / $divRes ))
    # Use basename to remove folder path
    echo `basename "${myArray[$i]}"` >> "$2/destFile$count"
done


编辑:在Charles Duffy发表评论之后,我删除了脚本文件名的扩展名。

如何使用
split
命令。例如,如果输入10个文件,我们需要3个输出文件,
split-d-l 3 file_list.txt文件将创建4个文件。
尝试第一个文件并删除它…很好。不过,我可以使用
${myArray[$I]##*/}
而不是
basename
来避免支付命令替换的费用。(我还避免鼓励人们在bash脚本上使用
.sh
扩展--
.sh
扩展鼓励人们运行
sh foo.sh
,避免使用shebang,这意味着脚本不能用完全不同的语言重写,而不需要修改所有调用方或使其名称具有误导性。我们不会这样做t运行
ls.elf
——脚本定义命令,并且命令在UNIX上通常没有扩展)。谢谢你的建议。它很有魅力。我也想出了一个方法,在帖子和现在之间做到这一点,这里是备用代码。数字4将是用户输入,但在这个例子中是固定的
tTotal=4 tRun=4,而read line do echo“$line”>>file_$tRun tRun=$(tRun-1))如果[[tRun-lt 1]];然后tRun=$ttotottal fi done
ls -l -d -1 $source/{*,.*} | tail -n +3 |  awk '{printf "%s\n",$9}' > hdpLoadList
fileCount=`ls -1 $source | wc -l`
threadCount=$3 

fptf=$(bc <<< "scale=1;($fileCount/$threadCount)+.9")
fptf=${fptf:0:1}

sPos=1
sLen=$fptf
for i in `seq 1 $threadCount`;
 do
   sed -n ${sPos},${sLen}p hdpLoadList | sed -e ':a;N;$!ba;s/\n/ /g' > hdpLoadP_$i
   sPos=$(($sPos+$fptf))
   sLen=$(($sLen+$fptf))
 done
#!/bin/bash

# Create an array with all the files
myArray=("$1"/*)

# Get array length
arrayLength=${#myArray[@]}

# Divide length by the third arg value
divRes=$(( $arrayLength / $3 ))

# Iterate through array using a counter
for ((i=0; i<${#myArray[@]}; i++)); do
    count=$(( $i / $divRes ))
    # Use basename to remove folder path
    echo `basename "${myArray[$i]}"` >> "$2/destFile$count"
done
bash split srcFolder destFolder 3