• linux学习:xargs与grep用法整理


    xargs

    xargs 是给命令传递参数的一个过滤器,也是组合多个命令的一个工具。

    xargs 可以将管道或标准输入(stdin)数据转换成命令行参数,也能够从文件的输出中读取数据。

    xargs 也可以将单行或多行文本输入转换为其他格式,例如多行变单行,单行变多行。

    xargs 默认的命令是 echo,这意味着通过管道传递给 xargs 的输入将会包含换行和空白,不过通过 xargs 的处理,换行和空白将被空格取代

    xargs 能够捕获一个命令的输出,然后传递给另外一个命令。

    之所以能用到这个命令,关键是由于很多命令不支持|管道来传递参数,而日常工作中有有这个必要,所以就有了 xargs 命令,例如:

    find /sbin -perm +700 |ls -l       #这个命令是错误的
    find /sbin -perm +700 |xargs ls -l   #这样才是正确的

    xargs 一般是和管道一起使用。

    命令格式:

    somecommand |xargs -item  command

    参数:

    • -a file 从文件中读入作为sdtin
    • -e flag ,注意有的时候可能会是-E,flag必须是一个以空格分隔的标志,当xargs分析到含有flag这个标志的时候就停止。
    • -p 当每次执行一个argument的时候询问一次用户。
    • -n num 后面加次数,表示命令在执行的时候一次用的argument的个数,默认是用所有的。
    • -t 表示先打印命令,然后再执行。
    • -i 或者是-I,这得看linux支持了,将xargs的每项名称,一般是一行一行赋值给 {},可以用 {} 代替。
    • -r no-run-if-empty 当xargs的输入为空的时候则停止xargs,不用再去执行了。
    • -s num 命令行的最大字符数,指的是 xargs 后面那个命令的最大命令行字符数。
    • -L num 从标准输入一次读取 num 行送给 command 命令。
    • -l 同 -L。
    • -d delim 分隔符,默认的xargs分隔符是回车,argument的分隔符是空格,这里修改的是xargs的分隔符。
    • -x exit的意思,主要是配合-s使用。。
    • -P 修改最大的进程数,默认是1,为0时候为as many as it can ,这个例子我没有想到,应该平时都用不到的吧。

    例子:
    cat test.txt | xargs -n 3                    #将单行划分为多行,每行3个字
    echo "splitxsplitxsplitxsplitx" | xargs -d x      #使用-d将x作为输入定界符(默认是使用IFS作为输入定界符的)
    echo "splitxsplitxsplitxsplitx" | xargs -d x -n 2   #将以上结果划分成多行,每行2个字
    cat args.txt | xargs -n 2 ./test.sh          #将参数写在args.txt中,每次可以修改-n的数字选择传多少个参数给脚本test.sh
    cat args.txt | xargs -I {} ./test.sh -p {} -l    #从args.txt读取参数,脚本test.sh每次需要传入3个参数,中间的参数为不固定的
    cat files.txt | xargs -I {} cat {}          #将接收到的参数打印出来
    cat files.txt | ( while read arg; do $arg; done )  #同上

    redis-cli KEYS "pattern" | xargs redis-cli DEL   #通过模糊匹配pattern正则,删除对应的redis键值对

    redis-cli -a password KEYS "godel*" | xargs redis-cli -a password DEL  #同上, -a参数指定密码


    注意:将命令输出作为xargs命令的输入的时候,最好为输出的各行添加一个0值字节终止符。xargs默认是使用空格最为定界符分割参数的。这样的话如果传入的单行输出中包含空格,那么会被以空格分割成多个参数。例如"This is test"传入xargs时,会被默认分割成3个参数。如果用0值字节终止符,那么就被作为定界符,此时,包括空格的单行就能正确地解析为单个参数了。所以在用的时候先加-0参数再加其他参数:xargs -0 ...


    grep

    语法:

    grep [-abcEFGhHilLnqrsvVwxy][-A<显示列数>][-B<显示列数>][-C<显示列数>][-d<进行动作>][-e<范本样式>][-f<范本文件>][--help][范本样式][文件或目录...]

    参数

    • -a 或 --text : 不要忽略二进制的数据。
    • -A<显示行数> 或 --after-context=<显示行数> : 除了显示符合范本样式的那一列之外,并显示该行之后的内容。
    • -b 或 --byte-offset : 在显示符合样式的那一行之前,标示出该行第一个字符的编号。
    • -B<显示行数> 或 --before-context=<显示行数> : 除了显示符合样式的那一行之外,并显示该行之前的内容。
    • -c 或 --count : 计算符合样式的列数。
    • -C<显示行数> 或 --context=<显示行数>或-<显示行数> : 除了显示符合样式的那一行之外,并显示该行之前后的内容。
    • -d <动作> 或 --directories=<动作> : 当指定要查找的是目录而非文件时,必须使用这项参数,否则grep指令将回报信息并停止动作。
    • -e<范本样式> 或 --regexp=<范本样式> : 指定字符串做为查找文件内容的样式。
    • -E 或 --extended-regexp : 将样式为延伸的普通表示法来使用。
    • -f<规则文件> 或 --file=<规则文件> : 指定规则文件,其内容含有一个或多个规则样式,让grep查找符合规则条件的文件内容,格式为每行一个规则样式。
    • -F 或 --fixed-regexp : 将样式视为固定字符串的列表。
    • -G 或 --basic-regexp : 将样式视为普通的表示法来使用。
    • -h 或 --no-filename : 在显示符合样式的那一行之前,不标示该行所属的文件名称。
    • -H 或 --with-filename : 在显示符合样式的那一行之前,表示该行所属的文件名称。
    • -i 或 --ignore-case : 忽略字符大小写的差别。
    • -l 或 --file-with-matches : 列出文件内容符合指定的样式的文件名称。
    • -L 或 --files-without-match : 列出文件内容不符合指定的样式的文件名称。
    • -n 或 --line-number : 在显示符合样式的那一行之前,标示出该行的列数编号。
    • -q 或 --quiet或--silent : 不显示任何信息。
    • -r 或 --recursive : 此参数的效果和指定"-d recurse"参数相同。
    • -s 或 --no-messages : 不显示错误信息。
    • -v 或 --revert-match : 显示不包含匹配文本的所有行。
    • -V 或 --version : 显示版本信息。
    • -w 或 --word-regexp : 只显示全字符合的列。
    • -x --line-regexp : 只显示全列符合的列。
    • -y : 此参数的效果和指定"-i"参数相同。

    例子:
    grep match_pattern filename     #在文件中搜索一个单词 match_pattern多为通配符或正则表达式
    grep "match_pattern" filename   #同上
    grep -E "[a-z]+" file        #要匹配正则则表达式需要加参数-E
    egrep "[a-z]+" file           #可以匹配正则表达式的搜索
    grep -c "text" filename       #统计文本中包含匹配字符串的行数,参数-c只是统计匹配行的数量,并不是匹配的次数
    grep word filename --color=auto #在输出行中重点标记出匹配到的单词
    grep -f pattern_file source_filename      #使用参数-f也是用于指定多个样式
    grep "main()" /data -r --include *.{c,cpp}     #只在/data目录中递归搜索所有的.c和.cpp文件
    grep "main()" /data -r --exclude "README"    #在搜索中排除所有的README文件,如果要排序目录则使用 --exclude-dir,如果要从文件中读取所需排除的列表则使用--exclude-from FILE
    grep -v  test  filename     #打印不包含test的所有行, 参数-v表示对包含某个字段进行过滤排除
    grep "match_pattern" file1 file2 file3...      #对多个文件进行搜索
    grep linux -n test.txt test2.txt          #参数-n是匹配结果行与其所属文件名一并打印出来
    echo gnu is not unix | grep -b -o "not"      #打印样式匹配所位于的字符或字节偏移,偏移量起始值为0,即该行第一个字符。-b和-o参数是配合使用的
    grep -l linux test1.txt test2.txt         #搜索过个文件并找出匹配文本位于哪个一个文件中,相反的选项有-L,它会返回一个不匹配的文件列表
    grep "match_pattern" . -R -n          #从当前目录开始,在多级目录中对文本进行递归搜索
    echo hello world | grep -i "HELLO"        #输出hello ,参数-i表示在匹配时不区分大小写
    echo this is a line. | grep -o -E "[a-z]+."    #结果:line. 参数-o表示只输出文件中匹配到的文本部分
    echo this is a line of text | grep -e "this" -e "line" -o #使用参数-e来指定匹配多个样式

    seq 10 | grep 5 -A 3     #参数-A打印5以及之后3行,也就是5,6,7,8
    seq 10 | grep 5 -B 3     #参数-B打印5以及之前3行,也就是2,3,4,5
    seq 10 | grep 5 -C 3     #参数-C打印5以及之前和之后3行,也就是2,3,4,5,6,7,8

    look word filepath    #列出文件中以特定单词起头的所有单词,如果没有给出文件参数,look命令会使用默认词典/usr/share/dict/words
    grep "^word" filepath  #同上

    grep '^$' /mydata/test*.log | wc -l   #查询mydata目录下test开通的log文件中空行数



    脚本例子1:测试文件是否包含特定的文本内容
    #!/bin/bash
    #filename:test.sh
    #执行:test.sh student test_data.txt
    if [ $# -ne 2 ];
    then
    echo "$0 match_text filename"
    fi
    match_text=$1
    filename=$2
    grep -q $match_text $filename    #参数-q使grep进入静默模式,只返回0或非0值,不会打印其他输出
    if [ $? -eq 0 ]
    then
    echo "The text exists in the file"
    else
    echo "The text not exists in the file"
    fi

    脚本例子2:统计特定文件中的词频
    #!/bin/bash
    #文件名:test.sh
    #执行:test.sh words.txt
    if [ $# -ne 1 ];
    then
    echo "Usage:$0 filename";
    exit -1
    fi
    filename=$1
    egrep -o "[[:alpha:]]+" $filename |
    awk '{ count[$0]++}
    END{ printf{"%-14s%s ","Word","Count"};
    for(ind in count)
    { printf("%-14s%d ",ind,count[ind]); }
    }'

    脚本例子3:拼写检查与词典操作
    法一:
    #!/bin/bash
    #filename:test.sh
    word=$1
    grep '^$1$' /usr/share/dict/brithish-english -q      #查找传入的参数是否在字典/usr/share/dict/brithish-english中。 ^表示正则的单词开头,$表示单词结尾,-q禁止产生任何输出
    if [ $? -eq 0 ] ;then
    echo $word is a dictionary word;
    else
    echo $word is not a dictionary word;
    fi

    法二:
    #!/bin/bash
    #filename:test.sh
    word=$1
    output=`echo "$word" | aspell list`     #当给定的输入不是一个词典单词时,aspell list命令将产生输出文本,反之则不产生任何输出。-z用于确认
    if [ -z $output ] ;then
    echo $word is a dictionary word;
    else
    echo $word is not a dictionary word;
    fi

    -------------------------------------------------

  • 相关阅读:
    潭州课堂25班:Ph201805201 django 项目 第二课 git 版本控制 (课堂笔记)
    HTML中的转义字符
    Java防止SQL注入
    Web很脆弱,SQL注入要了解
    防止sql注入:替换危险字符
    Hadoop HA详解
    java代码---charAt()和toCharry()的用法
    java代码-----计算器,界面+功能+boolean
    java代码-----运用endWith()和start()方法
    java代码---indexOf()方法
  • 原文地址:https://www.cnblogs.com/LO-gin/p/6891379.html
Copyright © 2020-2023  润新知