2017-08-29 115 views
0

我目前正在研究通过输入文件循环的脚本,输入文件的格式类似于Linux中的/ etc/hosts文件。例如,输入文件将是这个样子:KSH:将输出写入文件中间

192.168.1.21  host1 
192.168.1.17  host5 
192.168.1.168 host9 
192.168.1.3  host3 
192.168.1.37  host4 

从输入文件中的数据需要被添加到另一个文件(已经存在的主机文件),但它需要按照字母顺序进行排序。

下面的代码片段显示了我如何编码我的脚本。

#Assign parameters to variables 
inputFile=$1 
hostsFile=$2 

while read line 
do 

#Extract data from input file 
ipAddress=`echo $line | awk '{print $1}'` 
hostName=`echo $line | awk '{print $2}'` 

    #Loop to add host to hostname file, maintaining alphabetical order 
    while read line 
    do 
     addHost=`echo $line | awk '{print $2}'` 
     if [[ $profileEntry < $deviceName ]]; then 
      #Add device in sorted alphabetical order 
      echo $ipAddress "\t" $hostName >> $hostsFile 
      break; 
     fi 
    done < $hostsFile 

done < $inputFile 

我做字符串比较,但是当我写使用>>或>运营商输出将被追加到文件末尾的文件。是否有任何Linux ksh构造或其他方法可以在shell脚本中使用,这将允许我按字母顺序插入文本行,而不是将文本附加到文件末尾。

+1

操作系统本身没有插入操作。如果没有在* any *语言中重写所有内容,即使是C语言,也无法在文件中间插入数据。(也有例外,但它们需要特殊支持的文件系统,要插入的内容是块大小和块边界的精确倍数)。 –

+0

顺便说一句,'而读-r ipAddress hostName'会让你避免不必要的'awk'。如果'line = *'你在输出时得到一个文件名列表,那么tab会被空格替换,并且会发生各种其他的消息。 –

+0

同样,'printf'%s \ t%s \ n'“$ ipAddress”“$ hostName”'是一种更可靠的输出方式(不依赖于带XSI扩展名的'echo') –

回答

0

你所要求的是不可能的:操作系统本身没有办法在文件中插入(而不是替换)内容。除O_APPEND生效外,write()调用覆盖并在文件指针的当前位置之后立即替换任何内容。

从头开始编写一个新文件,并将其重命名为您要替换的原始文件;这有一个原子操作的好处:

#!/usr/bin/env ksh 

inputFile=$1 
hostsFile=$2 
tempFile=$(mktemp "${hostsFile}.XXXXXX") 

if sort -u -- "$inputFile" "$hostsFile" >"$tempFile"; then 
    mv -- "$tempFile" "$hostsFile" && exit 
fi 
rm -f -- "$tempFile"