Shell脚本逐行读取文件(不改变格式)(精选9篇)由网友“北平文化宫”投稿提供,以下是小编收集整理的Shell脚本逐行读取文件(不改变格式),希望对大家有所帮助。
篇1:Shell脚本逐行读取文件(不改变格式)
作者:vpsee 字体:[增加 减小] 类型:
这篇文章主要介绍了Shell脚本逐行读取文本文件,本文着重探讨不改变文本格式的方法读取出文件内容,需要的朋友可以参考下
网上有很多 shell script. 读文本文件的例子,但是都没有讲出故事的全部,只说了一半,举个例子,比如从一个 testfile 文件中读取如下格式的文本行:
代码如下:
$ vi testfile
ls -a -l /bin | sort
ls -a -l /bin | sort | wc
ls -a -l | grep sh | wc
ls -a -l
ls -a -l | sort | wc
最常见的一个 line by line 读取文件内容的例子就是:
代码如下:
$ vi readfile
#!/bin/sh
testfile=$1
while read -r line
do
echo $line
done < $testfile
$ chmod +x readfile
$ ./readfile testfile
ls -a -l /bin | sort
ls -a -l /bin | sort | wc
ls -a -l | grep sh | wc
ls -a -l
ls -a -l | sort | wc
这个例子的问题是读取文本行后,文本格式发生了变化,和原来 testfile 文件的内容不完全一致,空格字符自动被删除了一些。为什么会这样呢?因为 IFS,如果在 shell script. 里没有明确指定 IFS 的话,IFS 会默认用来分割空格、制表、换行等,所以上面文本行里多余的空格和换行都被自动缩进了。
如果想要输出 testfile 文件原有的格式,把每行(作为整体)原封不动的打印出来怎么办?这时需要指定 IFS 变量,告诉 shell 以 “行” 为单位读取,
代码如下:
$ vi readfile
#!/bin/sh
IFS=“”
testfile=$1
while read -r line
do
echo $line
done < $testfile
$ ./readfile testfile
ls -a -l /bin | sort
ls -a -l /bin | sort | wc
ls -a -l | grep sh | wc
ls -a -l
ls -a -l | sort | wc
上面两种方法的输出不是差不多吗,有什么关系呢,第一种还美观一些?关系重大,VPSee 昨天写了一个模拟 shell 的 C 程序,然后又写了一个 shell script. 来测试这个 C 程序,这个 script. 需要从上面的 testfile 里读取完整一行传给 C 程序,如果按照上面的两种方法会得到两种不同的输入格式,意义完全不同:
代码如下:
$./mypipe ls -a -l | sort | wc
$./mypipe “ls -a -l | sort | wc ”
显然我要的是第2种输入,把 “ls -a -l | sort | wc ” 作为整体传给我的 mypipe,来测试我的 mypipe 能不能正确识别出字符串里面的各种命令。
如果不用 IFS 的话,还有一种方法可以得到上面第二种方法的效果:
代码如下:
#!/bin/sh
testfile=$1
x=`wc -l $testfile |awk ‘{print $1}‘`
i=1
while [ $i -le $x ]
do
echo “`head -$i $testfile | tail -1`”
i=`expr $i + 1`
done
篇2:Shell逐行读取文件的4种方法
这篇文章主要介绍了Shell逐行读取文件的4种方法,本文介绍了while循环法、重定向法、管道法、文件描述符法等一些方法,需要的朋友可以参考下
在Linux中有很多方法逐行读取一个文件的方法,其中最常用的就是下面的脚本里的方法,而且是效率最高,使用最多的方法,为了给大家一个直观的感受,我们将通过生成一个大的文件的方式来检验各种方法的执行效率。
方法1:while循环中执行效率最高,最常用的方法。
代码如下:
function while_read_LINE_bottm{
While read LINE
do
echo $LINE
done < $FILENAME
}
注释:我习惯把这种方式叫做read釜底抽薪,因为这种方式在结束的时候需要执行文件,就好像是执行完的时候再把文件读进去一样。
方法2 : 重定向法;管道法: cat $FILENAME | while read LINE
代码如下:
Function While_read_LINE(){
cat $FILENAME | while read LINE
do
echo $LINE
done
}
注释:我只所有把这种方式叫做管道法,相比大家应该可以看出来了吧。当遇见管道的时候管道左边的命令的输出会作为管道右边命令的输入然后被输入出来。
方法3: 文件描述符法
代码如下:
Function while_read_line_fd(){
Exec 3<&0
Exec 0<$FILENAME
While read LINE
Do
Echo $LINE
Exec 0<&<3
}
注释: 这种方法分2步骤,第一,通过将所有内容重定向到文件描述符3来关闭文件描述符0.为此我们用了语法Exec 3<&0 。第二部将输入文件放送到文件描述符0,即标准输入。
方法4 for 循环。
代码如下:
function for_in_file(){
For i in `cat $FILENAME`
do
echo $i
done
}
注释:这种方式是通过for循环的方式来读取文件的内容相比大家很熟悉了,这里不多说。对各个方法进行测试,看那方法的执行效率最高。
首先我们用脚本(脚本见附件)生成一个70000行的文件,文件位置在/scripts/bigfile。然后通过下面的脚本来测试各个方法的执行效率,脚本很简单,不再解释。
代码如下:
#!/bin/bash
FILENAME=“$1”
TIMEFILE=“/tmp/loopfile.out” > $TIMEFILE
SCRIPT=$(basename $0)
function usage(){
echo -e “nUSAGE: $SCRIPT. file n”
exit 1
}
function while_read_bottm(){
while read LINE
do
echo $LINE
done < $FILENAME
}
function while_read_line(){
cat $FILENAME | while read LINE
do
echo $LINE
done
}
function while_read_line_fd(){
exec 3<&0
exec 0< $FILENAME
while read LINE
do
echo $LINE
done
exec 0<&3
}
function for_in_file(){
for i in `cat $FILENAME`
do
echo $i
done
}
if [ $# -lt 1 ] ; then
usage
fi
echo -e “ n starting file processing of each methodn”
echo -e “method 1:”
echo -e “function while_read_bottm”
time while_read_bottm >> $TIMEFILE
echo -e “n”
echo -e “method 2:”
echo -e “function while_read_line ”
time while_read_line >> $TIMEFILE
echo -e “n”
echo -e “method 3:”
echo “function while_read_line_fd”
time while_read_line_fd >>$TIMEFILE
echo -e “n”
echo -e “method 4:”
echo -e “function for_in_file”
time for_in_file >> $TIMEFILE
执行脚本后: [root@localhost shell]# ./while /scripts/bigfile
脚本输出内容:
代码如下:
method 1:
function while_read_bottm
real 0m5.689s
user 0m3.399s
sys 0m1.588s
method 2:
function while_read_line
real 0m11.612s
user 0m4.031s
sys 0m4.956s
method 3:
function while_read_line_fd
real 0m5.853s
user 0m3.536s
sys 0m1.469s
method 4:
function for_in_file
real 0m5.153s
user 0m3.335s
sys 0m1.593s
下面我们对各个方法按照速度进行排序,
代码如下:
real 0m5.153s method 4 (for 循环法)
real 0m5.689s method 1 (while 釜底抽薪法)
real 0m5.853s method 3 (标识符法)
real 0m11.612s method 2 (管道法)
由此可见在各个方法中,for语句效率最高,而在while循环中读写文件时,
代码如下:
while read LINE
do
echo $LINE
done < $FILENAME
方式执行效率最高。
篇3:Shell脚本一次读取文件中一行的2种写法
这篇文章主要介绍了Shell脚本一次读取文件中一行的2种写法,本文还同时讲解了Shell读取文本文件的2种方法,需要的朋友可以参考下
写法一:
代码如下:
#!/bin/bash
while read line
do
echo $line #这里可根据实际用途变化
done < urfile
写法二:
代码如下:
#!/bin/bash
cat urfile | while read line
do
echo $line
done
注意:以上代码中urfile 为被读取的文件
Shell读取文本文件
方法一:通过命令获取所需内容,传递给变量
代码如下:
var1=$(grep -i “^root” /etc/passwd | cut -d: -f 3 2>/dev/null) <=读取/etc/passwd文件中root的id
方法二:通过read命令读取这个文件
代码如下:
while read wOne wTwo wThree
do
[ -z $wOne ] && continue #测试此行内容是否为空
xxx=$wOne #提取内容
done < /var/xxx/one.txt
echo “$xxx” #变量获取了文件中的内容
以下方法无法提取内容;但可以输出,
Shell脚本一次读取文件中一行的2种写法
,
问题似乎出在bash对管道的处理方法上
(bash可能生成了一个子shell处理管道输出)。
代码如下:
cat /var/xxx/one.txt | while read wOne wTwo wThree
do
[ -z $wOne ] && continue #测试此行内容是否为空
xxx=$wOne #提取内容
done
echo “$xxx” #这里变量内容没有改变
篇4:shell下同时读取多个文件的方法
1. 单个文件的读取
在shell脚本下,可以多种方式实现按行读取文件,如下:
for line in `cat ${input_filename}`
do
echo $line
done
while read line
do
echo $line
done < ${input_filename}
其中第二种方式是将文件重定向到标准输入中
2. 多个文件读取方法
那如何实现同时多个文件的读呢?
我们可以继续利用bash中的文件重定向功能,将文件重定向到特定的文件描述符中,语法如下:
n
n>file
n>>file
nfile
这里的n代表打开文件file的文件描述符,类似其他编程语言中的fd,如果没有指定n,则其默认行为如下:
>file #same as 1>file
file #same as 0file
我们可以通过exec命令来打开所要重定向的文件:
exec 7
exec 8
然后我们可以通过read命令来读取对应文件的内容:
read data <&7 #使用符合是为了区分7是文件描述符,而不是文件名
read data <&8
关闭文件
exec 7
exec 8
多文件读取示例代码如下:
readfiles {
local FD1=7
local FD2=8
local file1=$1
local file2=$2
local count1=0
local count2=0
local eof1=0
local eof2=0
local data1
local data2
# Open files.
exec 7<$file1
exec 8<$file2
while [[ $eof1 -eq 0 || $eof2 -eq 0 ]]
do
if read data1<&$FD1; then
let count1++
printf “%s, line %d: %sn” $file1 $count1 “$data1”
else
eof1=1
fi
if read data2 <&$FD2; then
let count2++
printf “%s, line %d: %sn” $file2 $count2 “$data2”
else
eof2=1
fi
done
}
#read file1 and file2
readfiles file1 file2
篇5:Shell脚本实现从文件夹中递归复制文件
这篇文章主要介绍了Shell脚本实现从文件夹中递归复制文件,本文脚本实现从十层左右的文件夹中复制所有文件到一目录中,需要的朋友可以参考下
需求
前两天碰到需要在十层左右的文件夹中提取文件的需求,于是写了此脚本,
如下面这样的文件结构:
代码如下:
dir1
├── a
│ ├── b
│ │ └── file1
│ └── file2
├── c
│ └── d
│ ├── e
│ │ └── file4
│ └── file3
└── file5
我们需要将其中的file1~file5提取出来放到另一个文件夹中。
脚本
脚本getfilefromdir.sh如下:
代码如下:
#!/bin/bash
#desc: get file from directory
#example: sh getfilefromdir.sh A B
INIT_PATH=${1%/}
SAVE_PATH=${2%/}
function checksavepath() {
if [ -d $SAVE_PATH ]
then
rm -rf $SAVE_PATH
fi
mkdir ${SAVE_PATH}
touch $SAVE_PATH“.log”
}
function getfilefromdir(){
for file in ` ls $1`
do
if [ -d $1“/”$file ]
then
getfilefromdir $1“/”$file
else
local path=“$1/$file”
local name=$file
if [ ! -f $SAVE_PATH“/”$name ]
then
echo “cp ${path} to ${SAVE_PATH}/${name}”
cp ${path} “${SAVE_PATH}/${name}”
else
echo “${path} file already exists”
echo “${path}” >> $SAVE_PATH“.log” 2>&1
fi
fi
done
}
checksavepath
for sfol in ${INIT_PATH}
do
getfilefromdir ${sfol}
done
运行
代码如下:
sh getfilefromdir.sh dir1/ dir2
第一个参数是源文件夹,第二个是目地文件夹(不需要提前创建),
如果有同名文件,会存在dir2.log中
结果为:
代码如下:
dir2
├── file1
├── file2
├── file3
├── file4
└── file5
篇6:Shell脚本递归打印指定目录中所有目录文件
Shell脚本递归打印指定目录中所有目录文件#!/bin/bash#递归打印当前目录下的所有目录文件,
篇7:Shell脚本定期清空大于1G的日志文件
这篇文章主要介绍了Shell脚本定期清空大于1G的日志文件,本文直接给出实现代码,需要的朋友可以参考下
一个关于如何在指定文件大于1GB后,自动删除的问题,
批处理代码如下:
代码如下:
#!/bin/bash
# 当/var/log/syslog大于1GB时
# 自动将其备份,并清空
# 注意这里awk的使用
if ! [ -f /var/log/syslog ]
then
echo “file not exist!”
exit 1
fi
if [ `ls -l /var/log/syslog|awk ‘{print $5}‘` -gt $((1024*1024)) ]
then
cat /var/log/syslog >> ~/log/history # 将日志备份
echo >> ~/log/history # 增加一个空行
date >> ~/log/history # 记录时间
echo “-------------------------------------” >> ~/log/history
echo > /var/log/syslog # 清空
fi
篇8:用shell编出来的查看dbf文件的脚本Unix系统
#!/bin/ksh hd -abdA $1 |sed -n '1p' | cut -c7-70$HOME/tmp/FIRSTLINE$$ DBFFLAG=`awk '{print $1}' $HOME/tmp/FIRSTLINE$$` if [ $DBFFLAG -ne 3 ] then echo “这不是一个 数据库 文件!aa” exit 1 fi DEFSIZE=`awk '{print ($9+$10*256)}' $HOME/tmp/FIRS
#!/bin/ksh
hd -abdA $1 |sed -n '1p' | cut -c7-70>$HOME/tmp/FIRSTLINE$$
DBFFLAG=`awk '{print $1}' $HOME/tmp/FIRSTLINE$$`
if [ $DBFFLAG -ne 3 ]
then
echo “这不是一个数据库文件!aa”
exit 1
fi
DEFSIZE=`awk '{print ($9+$10*256)}' $HOME/tmp/FIRSTLINE$$`
STEP=`awk '{print ($11+$12*256)}' $HOME/tmp/FIRSTLINE$$`
dd if=$1 f=$HOME/tmp/DBFEND$$ bs=$DEFSIZE skip=1 2>/dev/null
fold -b -w$STEP $HOME/tmp/DBFEND$$
rm $HOME/tmp/FIRSTLINE$$
rm $HOME/tmp/DBFEND$$
> echo
注释:“这不是一个数据库文件!aa”,“ aa” 起啥子作用:响两下,要是那不是一个数据库文件就提示!使用很简单,如存为的名字为dbf的话那就:$ dbf user.dbf这是你想要查看的数据库文件,作用就是要是你有一个dbf文件,想看其中的内容,那就可以这样用了,这样还可以生成一个文件或引用管道输出给awk sed 这样命令,相信还是有点用的
原文转自:www.ltesting.net
篇9:Shell脚本实现根据文件的修改时间来分类文件
这篇文章主要介绍了Shell脚本实现根据文件的修改时间来分类文件,本文直接给出实现代码,需要的朋友可以参考下
#!/bin/bash# exctute# ./mod.sh file_type input_folder output_folder# ./mod.sh *.txt /tmp /data/# paramater count if [ ! $# -eq 3 ]; then echo “[ERROR] error paramater.” exitfi# file typefile_type=“${1}”# input foloderif [ -d “${2}” ]; then folder=“${2}”else echo “[ERROR] input folder is not exsit.” exit fi# output folderif [ -d “${3}” ]; then utput=“${3}”else echo “[ERROR] output folder is not exsit.” exitfi# search filefind ${folder} -name “${file_type}” | while read filename ; do # file type file_type=`echo ${filename##*.}` # file size file_size=`stat “${filename}” | sed -n ‘2,1p‘ | awk ‘{print $2}‘ ` # file modify time file_modify=`stat “${filename}” | sed -n ‘6,1p‘ | awk ‘{print $2, $3}‘ | sed -e ‘s/[-: ]//g‘ ` # output folder path=“${output}/${file_modify:0:6}” if [ ! -d “${path}” ]; then mkdir -p ${path} echo “folder(${path}) is created . ” fi # new file full name new_file_name=`echo ${path}/${file_modify}_[${file_size}].${file_type}` if [ ! -f “${new_file_name}” ]; then mv “${filename}” “${new_file_name}” else echo “file(${new_file_name}) is exsit, can not be removed. ” fidoneecho “finished !”exit
【Shell脚本逐行读取文件(不改变格式)(精选9篇)】相关文章:
linux中./configure命令参数解析linux操作系统2023-04-23
Linux UDP反弹shell脚本脚本安全2023-07-02
后门750字作文2022-09-01
linux当mysql以root权限登录时提权网站安全2023-08-17
如何保障Unix系统安全Windows系统2023-07-25
基于ARM体系的嵌入式系统BSP的程序设计2022-05-04
Authorware入门教程之开发多媒体课件的经验2023-09-25
FTP常用软件servu的安全权限处理WEB安全2022-12-10
Perl 脚本的特点数据库教程2022-09-28
WordPress数据备份方案2022-11-09