【问题标题】:Bash - Parse a long string using awk to separate wordsBash - 使用 awk 解析长字符串以分隔单词
【发布时间】:2014-06-24 14:06:35
【问题描述】:

我正在编写一个 bash 脚本来执行一些 mysqldump 备份。我不太擅长编写脚本。

我有:

#!/bin/bash
TNAMES="database1.tableA database2.tableD databaseN.tableZ"

我需要解析 TNAMES 以将数据库部分与表部分分开来执行 mysqldump

for TABLE in $TNAMES
do
  mysqldump $OPTIONS $USER $PASSWORD $DB $TABLENAME > "some_file.sql"
  (some more actions here)
done

所以在第一次循环迭代中,命令将是:

mysqldump $OPTIONS $USER $PASSWORD database1 tableA > "some_file.sql"

下一步:

mysqldump $OPTIONS $USER $PASSWORD database2 tableD > "some_file.sql"

下一步:

  mysqldump $OPTIONS $USER $PASSWORD databaseN tableZ > "some_file.sql"

等等。

有没有什么简单的方法可以用 awk 做到这一点?

【问题讨论】:

  • 你的问题不清楚,你写的剧本有什么困扰?
  • 您已经就该主题提出了一系列问题,并且尚未关闭(接受)之前的任何答案。而且这个问题根本不清楚。如果 awk 已经在工作,为什么还需要它?
  • 每个 >some_file.sql 将覆盖前一个,它们是不同的文件名还是您想要 >>some_file.sql

标签: bash shell parsing awk mysqldump


【解决方案1】:

您不需要 sed、awk 或 cut 来执行简单的前缀/后缀删除:

for spec in $TNAMES; do
  db=${spec%%.*}
  tb=${spec#*.}
  mysqldump ... $db $tb > $somewhere
done

【讨论】:

  • +1 用于使用子字符串操作。 $somewhere 应该类似于某处=$db-$tb.sql (否则只有最后一个转储可用)
  • @technosaurus:当然,sn-p 绝对不是 SCCCE。
  • 在引用变量后为正确的解决方案 +1(当然,$TNAMES 除外)。
  • @EdMorton 我会为我的无知辩护。你能告诉我一个 string $TNAMES 的定义,它会在for 循环中扩展到带有嵌入空格的单词吗?这是不可能的海事组织。
  • 在这种情况下,空格不是最可能出现的问题,它是通配符。如果 TNAMES 包含 *? 并且您在运行它的目录中有匹配的文件名,请尝试它。实际上,在这种情况下,这可能并不重要,因为无论如何您都需要不引用 TNAMES,但是引用变量应该是您的默认编码习惯 - 当您想要产生某些特定行为时,您会执行不引用变量的操作,例如在循环中扩展$TNAMES
【解决方案2】:

您可以为此使用“cut”:

for TABLE in $TNAMES
do
      DB=$(echo "$TABLE" | cut -d '.' -f 1)
      TABLENAME=$(echo "$TABLE" | cut -d '.' -f 2)
      mysqldump "$OPTIONS" "$USER" "$PASSWORD" "$DB" "$TABLENAME" > "some_file.sql"
done

【讨论】:

  • 在 OP 的示例中,这会反复覆盖 some_file.sql 而不使用它。
  • 我很清楚这一点。但这就是男孩要求的:)
  • 这可能适用于您当前的输入集,但总的来说它有一些问题:1)引用您的变量,2)避免回声,3)不需要剪切,4)反引号已被弃用。如果这适用于您当前的输入集,那么在将这种方法应用于任何其他问题之前,请确保您了解所有这些警告。
  • 感谢您的评论。我编辑了我的答案:变量现在被引用,反引号被替换为 $()​​。但是我为什么要避免回声呢?
【解决方案3】:

由于您在 bash 中启动变量,因此您可以使用数组:

Database[0]="database1"
Database[1]="database2"
...

Table[0]="tableA"
Table[1]="tableB"
...


# Loop over the table index
for i in $(seq 0 $((${#Database[@]}-1)))
do
   mysqldump $OPTIONS $USER $PASSWORD ${Database[$i]} ${Table[$i]} >> "some_file.sql"
done

我冒昧地处理文件>>,而不是每次都创建一个新文件。

【讨论】:

  • +1 表示数组建议。一旦你声明了对 bash(1) 的依赖,就没有理由半途而废。否则,您只会限制您的可部署性,以换取表现力。
【解决方案4】:

你也可以使用类似的东西

#!/bin/bash

TNAMES="database1.tableA database2.tableD databaseN.tableZ"
for TABLE in "$TNAMES"
do
    while IFS='.' read DB TABLENAME
    do 
      mysqldump "$OPTIONS" "$USER" "$PASSWORD" "$DB" "$TABLENAME" > "some_file.sql"
    done <<<"$TABLE";
done

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-11
    • 1970-01-01
    • 2012-05-13
    • 2014-06-30
    • 2010-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多