假设您有一个文件,其中包含 N 个以空格分隔的列和一个附加列,其中包含您想要保留的空格。
N = 2 的示例:
1.1 1.2 data for row1
2.1 2.2 data for row2
? ? data for row3
\ * data for row4
我想输出:
data for row1
data for row2
data for row3
data for row4
在 shell 中,您可以使用以下命令轻松完成此操作:
while read -r _ _ data
do
printf "%s\n" "$data"
done < data.txt
但awk
这样做有点困难。有没有一种方法awk
可以只拆分前 N 列?
如果数据由 1 个或多个空格分隔,则可以使用 sub 删除前 1 或 2 列,其中该列是由非空白字符组成的单个单词。
由于您的示例 shell 脚本也会在只有一个单词的情况下删除该单词,因此您可以对第二个单词使用可选部分。
模式匹配:
^
字符串的开头[[:space:]]*[^[:space:]]+
匹配可选空格和 1+ 个非空白字符([[:space:]]+[^[:space:]]+)?
可选择匹配 1+ 个非空白字符,后跟 1+ 个空格[[:space:]]*
匹配尾随空格输入
输出
免责声明:此解决方案假设您使用默认的 GNU
AWK
对字段的理解,即字段分隔符是一个或多个空白字符,如果这不成立,请完全忽略此答案。如果您先验知道 N,您可以准备正则表达式并将其用于
sub
String Function,特别是,令file.txt
content 为然后
给出输出
说明:正则表达式由空白字符
[[:space:]]
和非空白字符交替组成[^[:space:]]
,前导空白字符是可选的,因此数量为零或多个(*
),全部其他或 1 或多个( )。+
如果您确实需要有简单的方法来调整 N 使用
for
循环来逐一删除最左边的列,例如,如果您需要 N=3 并按file.txt
如上所示进行处理,您可以这样做给出输出
说明:这确实删除了每轮循环中最左边的列和相邻的字段分隔符
for
。(在 GNU Awk 5.1.0 中测试)
awk 语言的前提是,应该只存在一些结构来完成其他结构不易完成的事情,以保持语言简洁,从而避免其他一些工具/语言所遭受的语言膨胀。这只是有一个函数可以完成的众多事情之一,但是编写您实际需要执行的任何操作都非常容易,可以跳过任何特定输入的几个字段,这只会造成混乱语言,如果存在一个函数可以做到这一点,如果我们有一个函数可以做到这一点,那么还应该创建数百个其他函数来完成所有其他事情,如果有一个函数可以做到这一点那就太好了。
使用 GNU awk 进行
\s/\S
速记与任何 POSIX awk 相同:
请注意,上面的 awk 输出将保留任何尾随空格,这与 shell 读取循环不同。
这两个字符都依赖于默认的空白字符,但很容易修改为可以在括号表达式(或相反的字符类)中否定的
FS
任何其他字符。FS
请注意,整个方法依赖于能够否定括号表达式中的 ,因此如果是任意正则表达式甚至是多字符字符串,则
FS
该方法将不起作用,但您要求复制的 shell 读取循环也不会起作用FS
的函数.如果你碰巧有 a ,
FS
你不能只在括号表达式中取反,例如,如果你的字段由 3 个数字或 2 个标点字符分隔,那么你会得到如下内容:那么这里有一个更通用的方法,使用 GNU awk 作为第四个参数
split()
: