首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在sh脚本中调整grep的输出

在sh脚本中调整grep的输出
EN

Unix & Linux用户
提问于 2023-01-27 21:03:14
回答 2查看 58关注 0票数 0

晚上好,

我正在尝试grep,一个存储在MYSQL转储中的数据库列表,但是我想调整一些设置--我不知道该如何做。

目前的守则是;

代码语言:javascript
复制
#!/bin/sh

echo "What is the cPanel username!"
read cpuser

cd /home/${cpuser}/public_html

sqldump=$(find . -name \*.sql -type f)
sqlversion=$(grep "Server version" ${sqldump})
sqldbs=$(grep "CREATE DATABASE" ${sqldump})

echo "The dump location is"
echo $sqldump
echo "The SQL version is"
echo $sqlversion
echo "The databases in the dump are"
echo $sqldbs

它的输出是(在本例中)

代码语言:javascript
复制
What is the cPanel username!
domain1mysql4
The dump location is
./test/xxx/database/xxxx.sql
The SQL version is
-- Server version 4.1.14
The databases in the dump are
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `blog` /*!40100 DEFAULT CHARACTER SET latin1 */; CREATE DATABASE /*!32312 IF NOT EXISTS*/ `blog1` /*!40100 DEFAULT CHARACTER SET latin1 */; CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysql` /*!40100 DEFAULT CHARACTER SET latin1 */;

最后,我有两个问题。

是否可以只列出它输出'blog' 'blog1' 'mysql'的数据库,而不是行的其余部分?

是否也可以将这些变量保存为稍后在脚本中调用的变量?

弗雷迪调整后的输出

代码语言:javascript
复制
sh ./test.sh
enter the cPanel username: domain10mysql4
./home/saiprem/xxxxx/database/xxxx.sql:activesearch
./home/saiprem/xxxxx/database/x.sqxxxxl:alienstats
./home/saiprem/x/database/xxxxxx.sql:anahaw
xxxx./home/saiprem/x/databasxxxe/xxxx.sql:b2
./home/saiprem/x/database/x.sql:beeforumxxx
EN

回答 2

Unix & Linux用户

发布于 2023-01-27 23:44:00

对这一答案的假设:

  • 文件系统中可能存在零个或多个*.sql文件。
  • 调用Bash是允许的,我们使用它将数据库名存储在数组中
  • grep与Perl兼容的正则表达式(-P)可用于不输出不需要的匹配部分(\K)。
代码语言:javascript
复制
#!/bin/sh

read -p "enter the cPanel username: " cpuser
cd "/home/$cpuser/public_html"

find . -name \*.sql -type f -exec bash -c '
    echo "found $# sql dumps"
    for file; do
        version=$(grep -Poe "-- Server version \K.*" "$file")
        dbnames=( $(grep -Poe "CREATE DATABASE [^\`]*\`\K[^\`]*" "$file") )

        printf "\n          file: %s\n" "$file"
        printf "server version: %s\n" "$version"
        printf "%2s database(s): %s\n" "${#dbnames[*]}" "${dbnames[*]}"

        for dbname in "${dbnames[@]}"; do
            echo "do something with $dbname"
        done
    done
' 'find-sh' {} +

使用两个测试文件输出:

代码语言:javascript
复制
$ ./script.sh 
enter the cPanel username: me
./script.sh: 4: cd: can't cd to /home/me/public_html
found 2 sql dumps

          file: ./dump2.sql
server version: 4.1.14
 1 database(s): test
do something with test

          file: ./dump1.sql
server version: 4.1.14
 3 database(s): blog blog1 mysql
do something with blog
do something with blog1
do something with mysql

您可以看到该目录/home/me/public_html不存在,脚本需要进行错误处理。

编辑:

所有带有文件名前缀的数据库名称:

代码语言:javascript
复制
$ find . -name \*.sql -type f -exec grep -Poe "CREATE DATABASE [^\`]*\`\K[^\`]*" {} +
./dump2.sql:test
./dump1.sql:blog
./dump1.sql:blog1
./dump1.sql:mysql

所有已排序的数据库名称(添加-u以排序以删除重复项):

代码语言:javascript
复制
$ find . -name \*.sql -type f -exec grep -hPoe "CREATE DATABASE [^\`]*\`\K[^\`]*" {} + | sort
blog
blog1
mysql
test
票数 0
EN

Unix & Linux用户

发布于 2023-01-28 01:08:56

这样做的一种方法是过滤通过sed输出数据库名称的行。

数据库名称在输出中的一个共同点是"`“引号。

因此,您可以通过以下过程输送包含名称的行:

  1. 在每个引号之后加上一个新行
  2. 包含引号的所有行的Grep
  3. 用空格替换所有换行符
  4. 删除我认为将在每个名字的开头引号后面的空格。

这应该只输出该行引号中的名称。

请记住,我是在凌晨1点之后发布这个答案的,如果我正确地阅读了您的脚本,如果我不是哑巴,它应该如下所示:

代码语言:javascript
复制
echo $sqldbs | sed 's/\`/\`\n/' | grep "\`" | sed 's/\n/ /' | sed 's/\` /`/'

有点长,但它应该能把工作做完。

如果有任何问题,请告诉我。

票数 0
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/733389

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档