Awk/Bash编写脚本
我想写一段代码,输出awk和bash脚本。这个脚本基本上将一个文件切成小块,以便程序并行运行,我想控制PEICE的数量,而不是像现在这样设置一个数字。我当前的代码设置为使用awk将文件切割成10个部分,然后执行bash脚本Awk/Bash编写脚本,bash,awk,self,Bash,Awk,Self,我想写一段代码,输出awk和bash脚本。这个脚本基本上将一个文件切成小块,以便程序并行运行,我想控制PEICE的数量,而不是像现在这样设置一个数字。我当前的代码设置为使用awk将文件切割成10个部分,然后执行bash脚本 awk -v a=$a '{if (NR<(a/10)&&NR>=0) print }' $1 > $11 awk -v a=$a '{if (NR<(a/10*2)&&NR>=(a/10*1)) print }'
awk -v a=$a '{if (NR<(a/10)&&NR>=0) print }' $1 > $11
awk -v a=$a '{if (NR<(a/10*2)&&NR>=(a/10*1)) print }' $1 >$12
awk -v a=$a '{if (NR<(a/10*3)&&NR>=(a/10*2)) print }' $1 >$13
awk -v a=$a '{if (NR<(a/10*4)&&NR>=(a/10*3)) print }' $1 >$14
awk -v a=$a '{if (NR<(a/10*5)&&NR>=(a/10*4)) print }' $1 >$15
awk -v a=$a '{if (NR<(a/10*6)&&NR>=(a/10*5)) print }' $1 >$16
awk -v a=$a '{if (NR<(a/10*7)&&NR>=(a/10*6)) print }' $1 >$17
awk -v a=$a '{if (NR<(a/10*8)&&NR>=(a/10*7)) print }' $1 >$18
awk -v a=$a '{if (NR<(a/10*9)&&NR>=(a/10*8)) print }' $1 >$19
awk -v a=$a '{if (NR<=(a/10*10)&&NR>=(a/10*9)) print }' $1 >$110
bash $2 $11&
bash $2 $12&
bash $2 $13&
bash $2 $14&
bash $2 $15&
bash $2 $16&
bash $2 $17&
bash $2 $18&
bash $2 $19&
bash $2 $110&
我也不确定如何编写循环以给出以下代码:
cat $11.tab $12.tab $13.tab $14.tab $15.tab $16.tab $17.tab $18.tab $19.tab $110.tab > $3
这个答案并没有探讨像使用
split
或csplit
对文件进行分区这样的替代方法
假设a=$(wc-l<$1)
,并且$3
包含片段数(在本例中为10个),则可以使用seq
将现有代码打包为一个或两个循环,以生成所需的数字:
a=$(wc -l < "$1")
n=${3:-10}
for i in $(seq 1 $n)
do
# a = number of records in file
# n = number of parts the file is to be split into
# p = part number of current part
awk -v a=$a -v n=$n -v p=$i '{if (NR<(a/n*p)&&NR>=(a/n*(p-1))) print }' "$1" >"$1.$i"
bash "$2" "$1.$i" &
done
wait # For all the background processes to complete
这些代码都未通过
awk
或bash
,因此其中可能有错误。split
看起来更简单:
INPUT=$1 # input file
N=$2 # number of lines per file
SCRIPT=$3 # script to run
mkdir chunks
cd chunks
split "../$INPUT" -l "$N"
for file in *; do
bash "../$SCRIPT" "$file" &
done
您应该看看
split
命令,它可以替代您的一系列awk命令(并且只需扫描文件一次)。然后,您可以循环使用由split
生成的文件集,并发出并行bash命令。$110
可能是$20
的一个打字错误,应该是${20}
。所有两位数的位置参数都应该用大括号括起来。如果您的意思是${1}1
,${1}2
等,那么您应该使用大括号来明确说明(或使用点分隔部分$1.1
,或…。$a
中的值是多少?是不是$1
中的行数?如a=$(wc-l
或其他有关内容?请参阅编辑。。。split是一个值得了解的好程序。在这个程序中会为我保存几行。我能用cat*连接最后的所有文件吗(如果我把它们放在一个文件夹中),因为它是按字母顺序运行的?你介意解释一下n=语句吗,我不明白。您可以使用-v var=value
符号将shell变量作为awk
变量传递给awk
。因此,我将三个shell变量传递给第二个awk
脚本:$a
在awk
脚本中被调用a
,和$n
被调用n
,以及被调用f
。我可以使用-v lines=$a
从shell变量$a
在awk
中命名变量lines
;在shell和awk
中没有义务使用相同的名称(但这样做通常是有意义的)。对不起,我指的是n=${3:-10}语句ah:n=${3:-10}
表示“将n
设置为$3
的值,除非$3
未设置或为空,在这种情况下,使用默认值10”。
a=$(wc -l < "$1")
n=${3:-10}
awk -v a=$a -v n=$n -v f="$1" -e \
'{ nfn = int((n*NR)/a)+1;
if (nfn != ofn)
{
ofile = sprintf("%s.%d", f, nfn);
ofn = nfn;
}
print > ofile
}' "$1"
for i in $(seq 1 $3)
do
bash "$2" "$1.$i" &
done
wait # For all the background processes to complete
INPUT=$1 # input file
N=$2 # number of lines per file
SCRIPT=$3 # script to run
mkdir chunks
cd chunks
split "../$INPUT" -l "$N"
for file in *; do
bash "../$SCRIPT" "$file" &
done