Shell脚本如何实现对一个文件按关键字行来分成若干个小文件?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Shell脚本如何实现对一个文件按关键字行来分成若干个小文件?相关的知识,希望对你有一定的参考价值。
如一个文件中: 有5行包含关键字为FILE_TESTCASERESULT的行。那么我想把这个文件以这个关键字所在行为分割点,分割文件成5个小文件。请问大侠如何实现? ------- 初学shell的迷路人
五行关键字应该分割为6个文件啊?要不就是只取关键字行以下的行。
思路:用sed得出包含这个关键字的行的行号,然后根据行号分割文件。
#!/bin/shmyFile=TestResult.txt
num=5
count=0
line=`sed -n '/FILE_TESTCASERESULT/=' $myFile`
for n in $line
do
[ $count -eq 0 ] && let startLine=n+1 && continue
let count+=1
let endLine=n-1
[ $count -eq $num ] && endLine=`sed -n '$=' myFile`
sed -n "$startLine,$endLine p;q" $myFile >result_$count.txt
let startLine=n+1
done
结果保存到result_1.txt,result_2.txt,result_3.txt,result_4.txt,result_5.txt五个文件中。
注:关键字行本身不保存。如果要保存关键字行,请修改代码中的 let startLine=n+1 为 startLine=$n (两处地方)。
追问我需要保存关键字行和关键字行下面的内容:我把您的代码按照你说的修改代码中的 let startLine=n+1 为 startLine=$n (两处地方)。
如果$line的值是 1 3 5 7,那么似乎这个程序有问题
我的脚本是基于你说的前提:有5行包含关键字的行。你看我的代码里也设了个前提:num=5
如果行数不确定,是需要修改代码的。下面这样应该可以:
#!/bin/shmyFile=TestResult.txt
count=0
line=(`sed -n '/FILE_TESTCASERESULT/=' $myFile`) #Save in array
num=$#line[@] #Get array size
for n in $line[*]
do
[ $count -eq 0 ] && startLine=$n && continue
let count+=1
let endLine=n-1
[ $count -eq $num ] && endLine=`sed -n '$=' myFile`
sed -n "$startLine,$endLine p;q" $myFile >result_$count.txt
let startLine=n+1
done
上面的脚本是基于你说的前提:有5行包含关键字的行。你看我的代码里也设了个前提:num=5
如果行数不确定,是需要修改代码的。下面这样应该可以了:
#!/bin/shmyFile=TestResult.txt
count=0
line=(`sed -n '/FILE_TESTCASERESULT/=' $myFile`) #Save in array
num=$#line[@] #Get array size
for n in $line[*]
do
[ $count -eq 0 ] && startLine=$n && continue
let count+=1
let endLine=n-1
if [ $count -eq $num ]; then
startLine=$n
sed -n "$startLine,$ p" $myFile >result_$count.txt
else
sed -n "$startLine,$endLine p;q" $myFile >result_$count.txt
startLine=$n
fi
done
之前还有两处错误,有个myFile前面少了个$;startLine=$n 的位置也需要挪一下。
请用最后一个脚本。百度有问题,无法更新之前的回答而是直接显示到后面了。
追问第一次的file输出 count 1 startline:0,endline 0 不满足
且不知道为什么我这边报告说“[ $count -eq 0 ] && startLine=$n && continue” command not found
还有最后一部分的也是要存成一个文件谢谢
第一次的file输出 count 1 startline:0,endline 0 不满足
且不知道为什么我这边报告说“[ $count -eq 0 ] && startLine=$n && continue” command not found
还有最后一部分的也是要存成一个文件谢谢
你这边不支持continue关键字?那换一种方法:
#!/bin/shmyFile=TestResult.txt
count=0
startLine=(`sed -n '/FILE_TESTCASERESULT/=' $myFile`)
fileEnd=`sed -n '$=' $myFile`
endLine=(`echo $startLine[*] | awk -v a=$fileEnd 'for(i=2;i<=NF;i++) printf("%d ",$i-1);print a'`)
let maxIndex=$#startLine[@]-1
for n in `seq 0 $maxIndex`
do
sed -n "$startLine[$n],$endLine[$n] p;q" $myFile >result_$n.txt
done
startLine和endLine都存为数组,这样还简单些。
数组下标从0开始,所以,最大数组元素的下标(maxIndex)为数组长度减1。
参考技术A #!/bin/bash#By Spinestars
dl()
n1=1
sed "/$cut1/=" $path1 | sed '/^[0-9]\\1,2\\$/N;s/\\n/ /' | while read line
do
num=`echo $line | awk "/$cut1/print \\"$cut1\\""`
if [[ $cut1 == $num ]];then
echo $line | sed -n 's/^[0-9]\\1,2\\ //p'> "`pwd $path1`/$n1.file"
n2=$n1
n1=$[ $n1 + 1 ]
else
echo $line >> "`pwd $path1`/$n2.file"
fi
done
read -p "请输入文本路径(绝对路径):" path1
read -p "请输入段落分割符:" cut1
dl path1 cut1
测试文件:
[root@zyh shell]# cat testbFILEb
111
222
cFILEc
333
444
dFILEd
555
666
eFILEe
777
888
测试结果:
请输入文本路径(绝对路径):/root/shell/test
请输入段落分割符:FILE
[root@zyh shell]# ls
1.file 2.file 3.file 4.file
[root@zyh shell]# cat 1.file
bFILEb
111
222
[root@zyh shell]# cat 2.file
cFILEc
333
444
[root@zyh shell]# cat 3.file
dFILEd
555
666
[root@zyh shell]# cat 4.file
eFILEe
777
888
段落分割符可以任意,但是文本首行必须是含有段落分割符的行。如果不是,可以手动随便加一个含有段落分割符的行。
参考技术B csplit -f vcard -b %02d.vcard input.txt -z '/FILE_TESTCASERESULT/+1' '*' 参考技术C awk 'BEGINnum=1;prefix="file"if($0 ~ /FILE_TESTCASERESULT/)
print > prefix "_" num
num++
else
print > prefix "_" num
' file
Shell脚本实现按目录备份发布回滚
分享最近写的一段Shell脚本,用来实现按发布包的文件目录结构备份生产线文件,以及回滚操作。
1 #!/bin/sh 2 path="/home/www/site1" 3 pub=$path"/release/pub/MBOXII/trunk" #发布目录 4 bak=$path"/release/bak" #生产目录备份文件 5 prod=$path #生产目录 6 pub_file_plus=$path"/release/pub_plus.txt" #增量文件:发布包相对生产包的新增文件列表日志 7 8 #执行备份 9 dobak(){ 10 #删除之前的备份文件(夹) 11 for file in $(ls $bak) 12 do 13 #echo $bak"/"$file 14 rm -rf $bak"/"$file 15 done 16 if [ -f $pub_file_plus ] 17 then 18 rm -rf $pub_file_plus 19 fi 20 #将发布目录对应的生产目录的文件(夹)按原结构备份 21 function read_dir(){ 22 for file in `ls $1` 23 do 24 dir_r=$1"/"$file 25 dir_p=${dir_r/#$pub/$prod} 26 dir_b=${dir_r/#$pub/$bak} 27 if [ -d $dir_r ] #注意此处之间一定要加上空格,否则会报错 28 then 29 if [ -d $dir_p ] 30 then 31 #echo $dir_b 32 mkdir -p -m 755 $dir_b #创建对应的备份文件夹 33 read_dir $1"/"$file #递归子目录 34 else 35 echo $dir_p &>>$pub_file_plus 36 fi 37 else 38 if [ -f $dir_p ] 39 then 40 #echo $dir_p" "$dir_b 41 cp $dir_p $dir_b 42 else 43 echo $dir_p &>>$pub_file_plus 44 fi 45 fi 46 done 47 } 48 read_dir $pub 49 echo ‘备份完成‘ 50 } 51 52 #执行发布 53 dopub(){ 54 cp -arf $pub/* $prod 55 echo ‘发布完成‘ 56 } 57 58 #执行回滚 59 dorollback(){ 60 for file in $(cat $pub_file_plus) 61 do 62 #echo $bak"/"$file 63 rm -rf $file 64 done 65 cp -arf $bak/* $prod 66 echo ‘回滚完成‘ 67 } 68 69 usage() { 70 cat <<EOF 71 产品发布脚本使用方法: 72 1 备份 73 2 发布 74 3 回滚 75 4 退出 76 EOF 77 } 78 79 usage 80 echo ‘请输入操作指令:‘ 81 read cmd 82 while [ $cmd != ‘exit‘ ] 83 do 84 case $cmd in 85 1) 86 dobak 87 ;; 88 2) 89 dopub 90 ;; 91 3) 92 dorollback 93 ;; 94 4) 95 #exit 96 break 97 ;; 98 *) 99 usage 100 ;; 101 esac 102 echo ‘请输入操作指令:‘ 103 read cmd 104 done
以上是关于Shell脚本如何实现对一个文件按关键字行来分成若干个小文件?的主要内容,如果未能解决你的问题,请参考以下文章