使用 2 个字符分隔符进行剪切

使用 2 个字符分隔符进行剪切

我想使用 cut to 和 2 个字符分隔符来处理包含许多行的文件,如下所示:

1F3C6..1F3CA
1F3CF..1F3D3
1F3E0..1F3F0

但 cut 只允许单个字符。

而不是cut -d'..'我正在尝试,awk -F'..' "{echo $1}"但它不起作用。

我的脚本:

wget -O output.txt http://www.unicode.org/Public/emoji/6.0/emoji-data.txt                                                                             
sed -i '/^#/ d' output.txt                        # Remove comments                                                                                   
cat output.txt | cut -d' ' -f1 | while read line ;                                                                                                    
  do echo $line | awk -F'..' "{echo $1}"                                                                                                             
done  

答案1

awk只要 的字段分隔符超过两个字符,就会被视为正则表达式。..作为正则表达式,表示任意 2 个字符。你需要.[.]或 with 来逃避它\.

awk -F'[.][.]' ...
awk -F'\\.\\.' ...

(反斜杠本身也需要转义(至少对于一些像 gawk 这样的 awk 来说),以便参数进行\n/扩展)。\b-F

在你的情况下:

awk -F' +|[.][.]' '/^[^#]/{print $1}' < output.txt

任何状况之下,避免 shell 循环处理文本, 注意read不应该这样使用, 那echo不应该用于任意数据记得引用你的变量

答案2

对我有用的示例测试脚本:

#!/bin/sh

raw="1F3C6..1F3CA
1F3CF..1F3D3
1F3E0..1F3F0"

for r in $raw
do
    f1=`echo "${r}" | cut -d'.' -f1`
    f2=`echo "${r}" | cut -d'.' -f2`
    f3=`echo "${r}" | cut -d'.' -f3`
    echo "field 1:[${f1}] field 2:[${f2}] field 3:[${f3}]"
done

exit

输出是:

field 1:[1F3C6] field 2:[] field 3:[1F3CA]
field 1:[1F3CF] field 2:[] field 3:[1F3D3]
field 1:[1F3E0] field 2:[] field 3:[1F3F0]

编辑

阅读 Stéphane Chazelas 评论和链接的问答后,我重写了上面的内容以删除loop.

我无法找到一种方法来删除loop 将这些部分保留为可以传递的变量(例如;$f1$f2以及在我原来的答案中)。$f3我仍然不知道原始问题中需要输出什么。

首先,仍然使用cut

#!/bin/sh
raw="1F3C6..1F3CA
1F3CF..1F3D3
1F3E0..1F3F0"

printf '%s\n' "${raw}" | cut -d'.' -f1,3

这将输出:

1F3C6.1F3CA
1F3CF.1F3D3
1F3E0.1F3F0

.可以使用--output-delimiter=STRING.替换显示的任何字符串。

接下来,用 withsed代替,cut以便更好地控制输出:

#!/bin/sh
raw="1F3C6..1F3CA
1F3CF..1F3D3
1F3E0..1F3F0"

printf '%s\n' "${raw}" | sed 's/^\(.*\)\.\.\(.*\)$/field 1 [\1] field 2 [\2]/'

这将呈现:

field 1 [1F3C6] field 2 [1F3CA]
field 1 [1F3CF] field 2 [1F3D3]
field 1 [1F3E0] field 2 [1F3F0]

答案3

您可以使用 IFS 分割每一行,丢弃两个点之间的字段:

#/bin/sh
while IFS=\. read a _ b
do
     echo "field one=[$a] field two=[$b]"
done < "file"

执行:

$ ./script
field one=1F3C6 field two=1F3CA
field one=1F3CF field two=1F3D3
field one=1F3E0 field two=1F3F0

假设该文件是:

$ cat file
1F3C6..1F3CA
1F3CF..1F3D3
1F3E0..1F3F0

答案4

我已经创建了一个补丁向 中添加了新的-m命令行选项cut,该选项在字段模式下工作并将多个连续分隔符视为单个分隔符。这基本上以相当有效的方式解决了OP的问题。几天前我也在上游提交了这个补丁,希望它能被合并到 coreutils 项目中。

有一些进一步的想法关于向 中添加更多与空白相关的功能cut,并就所有这些提供一些反馈,那就太好了。我愿意实现更多补丁并向cut上游提交它们,这将使该实用程序在各种现实场景中更加通用和更可用。

相关内容