首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用UNIX脚本中的模式拆分文件

使用UNIX脚本中的模式拆分文件
EN

Stack Overflow用户
提问于 2018-10-31 00:05:45
回答 2查看 53关注 0票数 0

我有一个要拆分的文件。该文件将具有头部和尾部记录。文件的主体包含NFD和IV记录。IV记录是可选的。在NFD记录中,它将在某个地方包含英语、法语或法语。对于英语,我希望NFD和IV转到en.txt,否则转到fr.txt。

示例如下:

代码语言:javascript
复制
 1. 000000000000000;HDR;1;...
 2. 000000008651776;NFD;Individual;...;English;...
 3. 000000008651776;IV;....
 4. 000000008657876;NFD;Individual;...;English;...
 5. 000000008751796;NFD;Individual;...;French;...
 6. 000000008751796;IV;...
 7. 999999999999999;TRL;...

我希望1,2,3,4,7行都转到en.txt,1,5,6,7行转到fr.txt

有什么建议使用K-shell脚本吗?谢谢!

EN

回答 2

Stack Overflow用户

发布于 2018-10-31 19:28:12

对于此任务,您需要实现状态解析。我不认为ksh只是一个重要的解决方案。

awk解决方案,以防万一:

代码语言:javascript
复制
$ awk '
/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9];HDR/ { enfile=enfile $0 RS; frfile=frfile $0 RS; }
/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9];NFD.*;English/ { enflag=1; frflag=0; enfile=enfile $0 RS; }
/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9];NFD.*;French/ { enflag=0; frflag=1; frfile=frfile $0 RS; }
/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9];IV/ { if ( enflag==1 ) enfile=enfile $0 RS; if ( frflag==1 ) frfile=frfile $0 RS; }
/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9];TRL/ { enfile=enfile $0; frfile=frfile $0; }
END { print(enfile) > "en.txt"; print(frfile) > "fr.txt"; }
' en_fr.txt

$ cat en.txt
000000000000000;HDR;1;...
000000008651776;NFD;Individual;...;English;...
000000008651776;IV;....
000000008657876;NFD;Individual;...;English;...
999999999999999;TRL;...

$ cat fr.txt
000000000000000;HDR;1;...
000000008751796;NFD;Individual;...;French;...
000000008751796;IV;...
999999999999999;TRL;...

注意:如果您在/^[0-9]{15}/上,我使用regexp style: UNIX并不是为了具有本机awk兼容性。

票数 0
EN

Stack Overflow用户

发布于 2018-11-05 06:25:48

我相信这会做你想要的。这是在Linux上用ksh编写的,但可以在大多数版本的Unix上与bash或其他操作系统一起使用。

代码语言:javascript
复制
#!/bin/ksh
rm -f english.out
rm -f french.out
output=both
while read linein
do
    echo $linein | grep HDR     >/dev/null && output=both
    echo $linein | grep English >/dev/null && output=english
    echo $linein | grep French  >/dev/null && output=french
    echo $linein | grep TRL     >/dev/null && output=both
    case $output in
    both)
        echo "$linein" >> english.out
        echo "$linein" >> french.out
    ;;
    english)
        echo "$linein" >> english.out
    ;;
    french)
        echo "$linein" >> french.out
    ;;
    esac
done < data.txt

通过解释的方式:

  1. 在开始时删除旧的输出文件。
  2. output变量设置为both。
  3. while循环正在读取data.txt文件,一次一行读取linein变量。( while...done循环将其输入从data.txt文件重定向。)
  4. (有些人会觉得这样很乱)我们将每一行都回显到grep,丢弃输出,只保留退出状态。如果退出状态为success,则设置输出。如果退出状态为false,则不会更改输出。这允许我们将NFD记录发送到与前面的记录相同的位置。
  5. 案例在不同的输出值之间切换,以决定将输出发送到哪里。我想您应该知道>>意味着将输出追加到文件中。请注意$linein周围的引号。如果它们不在那里,您就不能保留输入中的空格。这对你来说似乎无关紧要。

如果您只想在字段5中查找英语或法语,它将变得更加复杂(并且不适用于bash (或ksh的旧版本)):

代码语言:javascript
复制
#!/bin/ksh
rm -f english.out
rm -f french.out
output=unknown
while read linein
do
    if [[ $linein == {15}(\d)\;HDR* || $linein == {15}(\d)\;TRL* ]]
    then
        output=both
    else
        if [[ $linein == {15}(\d)\;+([A-Z])\;+([^\;])\;+([^\;])\;+([^\;])\;* ]]
        then
            case ${.sh.match[5]} in
                English)
                    output=english
                ;;
                French)
                    output=french
                ;;
                *)
                    echo "unknown language: ${.sh.match[5]}" >&2
                    output=both
                ;;
            esac
        fi
    fi
    case $output in
        both)
            echo "$linein" >> english.out
            echo "$linein" >> french.out
        ;;
        english)
            echo "$linein" >> english.out
        ;;
        french)
            echo "$linein" >> french.out
        ;;
        *)
        echo "Unknown output: $output" >&2
        ;;
    esac
done < data.txt

${.sh.match[5]}在匹配字符串( paren ()中的片段)中包含#5子表达式。

使用awk拉出子表达式更简单,但这是一个纯ksh解决方案。

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

https://stackoverflow.com/questions/53068436

复制
相关文章

相似问题

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