Bash:检查文件是否包含其他文件内容

时间:2016-09-16 11:47:55

标签: bash shell awk grep append

所以我试图将一个文件的内容附加到另一个文件中(如果它尚未包含在内)。这是我尝试的方式:

catAndAppendIfMissing(){
    [[ ! -s $2 ]] && touch "$2" || [[ ! -s $2 ]] && sudo touch "$2"
    if grep $1 $2; then
        echo "found"
    else
        catAndAppend $1 $2       #this appends file $1 contents to file $2 (and takes care of adding newlines if needed and uses sudo if needed, thus the separate function)
    fi
}

使用if grep $1 $2我试图查看文件$ 2中是否存在$ 1内容。这是不能按预期工作的部分:
当我在同一个文件上运行两次时,它只会将相同的文本两次附加到目标文件。

我该如何解决?

专业:

  • 我在OSX 10.11.5上(但Linux /跨平台的解决方案也可能对我在家里或其他人阅读此内容都有用)。
  • 我选择在cat $file1 >> $file2上使用catAndAppend是为了处理需要sudo的情况,并根据需要添加新行,将附加内容与已经存在的内容分开。
  • 如果文件$ 1在文件$ 2中的任何位置(不仅在开头或结尾),我都不想附加
  • 有关信息,请参阅我尝试过的文件$ 1内容之一:

alias ls='ls -a'
alias mkdir="mkdir -pv"
alias wget="wget -c"
alias histg="history | grep"
alias echopath='echo $PATH | tr -s ":" "\n"'
alias myip="curl -sSL http://ipecho.net/plain | xargs echo"
alias webpic="mogrify -resize 690\> *.png"

alias cddog='cd ~/dev/go/src/github.com/dogtools/dog'
alias xp='cd ~/dev/go/src/experiments'
  • 但我需要将其与其他包含var导出,代码,命令,配置,任何类型文本的文件一起使用

4 个答案:

答案 0 :(得分:2)

如果文件$1中的文件$2 ,请不要附加

catAndAppendIfMissing(){
    f1=$(wc -c < "$1")
    diff  -y <(od -An -tx1 -w1 -v "$1") <(od -An -tx1 -w1 -v "$2") | \
    rev | cut -f2 | uniq -c | grep -v '[>|]' | numgrep /${f1}../ | \
    grep -q -m1 '.+*' || cat "$1" >> "$2";     }

工作原理:

  1. 使用$1计算文件wc中的字符数。
  2. 使用od生成两个文件的每行hex dump一个字节,并使用bash主题,获取diff file,其中包含...
  3. rev,然后cut 2nd 字段,并对具有空白而不是&#39;&gt;的连续行进行uniq计数&#39; S
  4. 如果其中一个计数等于或大于$f1,则可以追加。这可以使用变量进行检查,但numgrep很方便,有助于避免变量。
  5. 注记。好:也适用于二进制文件。错误:低效,od会读取整个文件,diff会读取整个od的输出。如果 file1 是一行字符串,它位于1TB file2 的第一行,则会浪费很多时间。

    (旧版本)。如果文件$1已经附加到文件$2,请不要附加:

    catAndAppendIfMissing(){
        f1=$(wc -c < "$1")
        f2=$(wc -c < "$2")
        [ $f1 -le $f2 ] &&  cmp -s "$1" "$2" 0 $(( $f2 - $f1 )) && return 1 
        cat "$1" >> "$2"
        }
    

    工作原理:

    1. 使用wc获取文件长度,存储在$f1$f2
    2. 如果第一个文件更长而不是第二个文件,(或者如果cmp显示第一个文件不是已经已经附加到第二个文件),然后将其附加到cat的第二个文件。否则return会显示错误代码。

答案 1 :(得分:1)

尝试有条件地更新文件可能不值得;只需获取每个文件以确保定义了所有别名,然后无条件地将alias的输出存储到您要附加到的文件中。

source "$1"   # Original aliases
source "$2"   # New aliases
alias > "$1"  # Combined aliases

答案 2 :(得分:0)

行:

if grep $1 $2 

应该是:

if grep `cat $1` $2

OR

file1_Content=`cat $1`

if grep ${file1_Content} $2

OR

file1_Content=`cat $1`
grep ${file1_Content} $2

if [ $? == 0 ];then
  echo "found"
else
  #catAndAppend
fi

答案 3 :(得分:0)

所以我完成了我的作业并提出了一个(几乎)适合该法案的解决方案,唯一的区别在于它是用python而不是bash完成的。然后从bash调用我的python脚本。

所以这是代码:

import re, os, subprocess, mmap, sys, pprint 

def isFile1InFile2(file1Path, file2Path): 
    with open(file2Path) as file2: 
        file2Access = mmap.mmap(file2.fileno(), 0, access=mmap.ACCESS_READ) 
        file1Contents = open(file1Path).read() 
        if file2Access.find(file1Contents) != -1: 
            return True 
        else: 
            return False 

def appendIfMissing(source, dest): 
    destFullPath = os.path.expanduser(dest) 
    if os.path.isfile(destFullPath): 
        if isFile1InFile2(source, destFullPath): 
            print ('Source\'s contents found in dest file, no need to append') 
        else: 
            print('Source\'s contents cannot be found in dest file, appending...') 
            # append source file to destfile 
            command = ' '.join(['source', './common/configs/.shell-functions', '&&', 'catAndAppend', source, destFullPath]) 
            os.system(command) 

    else: 
        print "destfile not a file yet, copying sourcefile to destfile..." 
        # copy source file to destfile 
        command = ' '.join(['source', './common/configs/.shell-functions', '&&', 'catAndAppend', source, destFullPath]) 
        print command 
        os.system(command)

if len(sys.argv) != 3:
    sys.exit('[ERROR] appendIfMissing.py, line 31: number of arguments passed is not 3')
else:
    appendIfMissing(sys.argv[1], sys.argv[2])

然后从bash中调用它:

appendIfMissing(){ 
    python ./common/configs/appendIfMissing.py $1 $2 
} 

使用bash函数(从python调用的函数)保持不变:

createFileIfMissing(){
    # create file if doesn't exist, with right permission
    [[ ! -s $1 ]] && touch "$1" || [[ ! -s $1 ]] && sudo touch "$1"
}

addNewLineToFile(){
    [[ ! -e $1 ]] || [[ -w $1 ]] && printf "\n" >> $1 || [[ -e $1 ]] && [[ ! -w $1 ]] && sudo bash -c "printf \"\n\" >> $1"
}

catAndAppend(){ 
    createFileIfMissing $2 
    # append stuff to it 
    [[ ! -e $2 ]] || [[ -w $2 ]] && cat $1 >> $2 || [[ -e $2 ]] && [[ ! -w $2 ]] && sudo bash -c "cat $1 >> $2" 
    addNewLineTo $2 
} 

缺点:

  • 这不是bash。我在问题中要求一个bash解决方案(但我真正关心的是解决方案)
  • 这不是bash。因为它是用于系统设置脚本的,所以我必须首先安装python才能工作。但我想最终还是安装了它。

优点:

  • 它比bash恕我直言更易读/可维护/可定制(作为这两种语言的新手,python更直观的开始)
  • 这是跨平台