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

问题描述 投票:0回答:4

因此,我尝试将一个文件的内容附加到另一个文件(如果尚未包含)。这就是我尝试的方法:

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
我试图查看文件 $1 的内容是否存在于文件 $2 中。这就是未按预期工作的部分:
当我在同一个文件上运行两次时,它只会将相同的文本两次附加到目标文件。

我该如何解决这个问题?


精度:

  • 我使用的是 OSX 10.11.5(但是 Linux/跨平台的解决方案也可能与我在家或阅读本文的其他人相关)
  • 我选择使用 catAndAppend 而不是
    cat $file1 >> $file2
    是为了处理需要 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 导出、代码、命令、配置、基本上任何类型的文本的其他文件一起使用
bash shell awk grep append
4个回答
4
投票

如果文件

$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
    生成两个文件每行一个字节 十六进制转储,并使用
    bash
    主义,获得一个
    diff
    文件
    ,该文件通过管道传输到...
  3. rev
    ,然后
    cut
    2nd 字段,并对包含空格而不是 '> 的连续行进行
    uniq
    计数。
  4. 如果其中一个计数等于或大于
    $f1
    ,则可以追加。这可以用变量来检查,但是
    numgrep
    很方便,有助于避免变量。

注释。好:也适用于二进制文件。不好:效率低下,

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
投票

可能不值得尝试有条件地更新文件;只需获取每个文件以确保定义所有别名,然后无条件地将

alias
的输出存储到您要附加到的文件中。

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

0
投票

线路:

if grep $1 $2 

应该是:

if grep `cat $1` $2

file1_Content=`cat $1`

if grep ${file1_Content} $2

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

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

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 更直观)
  • 跨平台
© www.soinside.com 2019 - 2024. All rights reserved.