我如何分解像 split 到 stdout 这样的文件以通过管道传输到命令?

Ehr*_*ryk 8 shell text-processing split stdout

我有一个大.sql文件,里面装满了SELECT我想插入到我的 SQL Server 数据库中的数据的语句。我正在寻找如何基本上获取文件的内容,一次 100 行,并将其传递给我设置的命令来完成其余的工作。

基本上,我正在寻找split将输出到stdout,而不是文件。

我也在 Windows 上使用 CygWin,所以我无法访问全套工具。

Gra*_*eme 5

我认为最简单的方法是:

while IFS= read -r line; do
  { printf '%s\n' "$line"; head -n 99; } |
  other_commands
done <database_file
Run Code Online (Sandbox Code Playgroud)

您需要read在每个部分的第一行使用,因为在到达文件末尾时似乎没有其他方法可以停止。有关更多信息,请参阅:


don*_*sti 5

基本上,我正在寻找split将输出到stdout,而不是文件。

如果您有权访问gnu split,则该--filter选项会执行以下操作:

‘--filter=command’

    With this option, rather than simply writing to each output file, write
    through a pipe to the specified shell command for each output file.
Run Code Online (Sandbox Code Playgroud)

所以在你的情况下,你可以使用这些命令--filter,例如

split -l 100 --filter='{ cat Header.sql; cat; } | sqlcmd; printf %s\\n DONE' infile
Run Code Online (Sandbox Code Playgroud)

或写一个脚本,例如myscript

#!/bin/sh

{ cat Header.sql; cat; } | sqlcmd
printf %s\\n '--- PROCESSED ---'
Run Code Online (Sandbox Code Playgroud)

然后简单地运行

split -l 100 --filter=./myscript infile
Run Code Online (Sandbox Code Playgroud)


Ehr*_*ryk 1

我最终得到了一些看起来很恶心的东西,如果有更好的方法请发布:

#!/bin/sh

DONE=false
until $DONE; do
    for i in $(seq 1 $2); do 
        read line || DONE=true;
        [ -z "$line" ] && continue;
        lines+=$line$'\n';
    done
    sql=${lines::${#lines}-10}
    (cat "Header.sql"; echo "$sql";) | sqlcmd
    #echo "--- PROCESSED ---";
    lines=;
done < $1
Run Code Online (Sandbox Code Playgroud)

Run with./insert.sh "File.sql" 100其中 100 是一次要处理的行数。