Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 在awk中打印其余字段_Bash_Awk - Fatal编程技术网

Bash 在awk中打印其余字段

Bash 在awk中打印其余字段,bash,awk,Bash,Awk,假设我们有这个数据文件 john 32 maketing executive jack 41 chief technical officer jim 27 developer dela 33 assistant risk management officer 我想使用awk john maketing executive jack chief technical officer jim developer dela assistant risk management officer 我知

假设我们有这个数据文件

john 32 maketing executive
jack 41 chief technical officer
jim  27 developer
dela 33 assistant risk management officer
我想使用
awk

john maketing executive
jack chief technical officer
jim  developer
dela assistant risk management officer
我知道可以使用
for
来完成

awk '{printf $1;  for(i=3;i<=NF;i++){printf " %s", $i} printf "\n"}' < file
awk'{printf$1;for(i=3;i设置要跳到空白的字段:

awk '{$2 = ""; print $0;}' < file_name
awk'{$2=”“;打印$0;}'

来源:

您可以像这样使用简单的awk:

awk '{$2=""}1' file
然而,这将有一个额外的OFS在您的输出,可以避免这个awk

awk '{sub($2 OFS, "")}1' file
或者使用此tr和cut组合:

在Linux上:

tr -s ' ' < file | cut -d ' ' -f1,f3-
tr -s ' ' < file | cut -d ' ' -f1 -f3-
tr-s'
在OSX上:

tr -s ' ' < file | cut -d ' ' -f1,f3-
tr -s ' ' < file | cut -d ' ' -f1 -f3-
tr-s'
这将删除字段2并清理多余的空间

awk '{$2="";sub("  "," ")}1' file

另一种方法是仅使用sed替换第一个数字和空格匹配:


sed的|[0-9]\+\s\+| |文件

在使用默认FS时,使用GNU awk for gensub()可靠:

$ gawk -v delNr=2 '{$0=gensub("^([[:space:]]*([^[:space:]]+[[:space:]]+){"delNr-1"})[^[:space:]]+[[:space:]]*","\\1","")}1' file
john maketing executive
jack chief technical officer
jim  developer
dela assistant risk management officer
对于其他awk,需要使用match()和substr()而不是gensub()。请注意,上面的变量delNr告诉awk要删除的字段:

$ gawk -v delNr=3 '{$0=gensub("^([[:space:]]*([^[:space:]]+[[:space:]]+){"delNr-1"})[^[:space:]]+[[:space:]]*","\\1","")}1' file
john 32 executive
jack 41 technical officer
jim  27
dela 33 risk management officer
不要这样做:

awk '{sub($2 OFS, "")}1'
awk '{$2=""}1' file
awk '{$2="";sub("  "," ")}1' file
由于$2中的同一文本可能位于$1的末尾,和/或$2可能包含RE元字符,因此很有可能以这种方式删除错误的字符串

不要这样做:

awk '{sub($2 OFS, "")}1'
awk '{$2=""}1' file
awk '{$2="";sub("  "," ")}1' file
因为它添加了一个FS,并将字段之间的所有其他连续空白压缩为单个空白字符

不要这样做:

awk '{sub($2 OFS, "")}1'
awk '{$2=""}1' file
awk '{$2="";sub("  "," ")}1' file
因为它有上面提到的空间压缩问题,并且依赖于一个空白的硬编码FS(虽然是默认的,所以可能不是那么糟糕),但更重要的是,如果$1之前有空格,它将删除其中一个,而不是它在$1和$2之间添加的空格


最后值得一提的是,在gawk的最新版本中,有一个名为patsplit()的新函数,它的工作原理与split()类似但除了创建一个字段数组之外,它还创建了一个字段之间的空格数组。这意味着,您可以在数组中操作字段以及字段之间的空格,这样您就不必担心在操作字段时awk会使用OFS重新编译记录。然后您只需打印所需的字段数组中的ant。有关更多信息,请参见中的patsplit()。

使用不需要
gawk
或任何状态突变的
awk
方法:

awk '{print $1 " " substr($0, index($0, $3));}' datafile
UPD

稍长一点的解决方案,但在$1或$2包含$3的情况下仍然有效:

awk '{print $1 " " substr($0, length($1 $2) + 1);}' data
或者,如果您有自定义字段分隔符,则更加健壮:

awk '{print $1 " " substr($0, length($1 FS $2 FS) + 1);}' data


不要使用$n。如果你想保留的某个部分有更多的空格,它会减少到一个。

一个简单的方法是将$2设置为“”,然后打印$0(所有字段)——尽管这会为空字段提供一个额外的分隔符。3年后,你帮助了我。但是你应该更改“3年后,我编辑了这个问题以改变它应该是
cut-d'-f1,3-
@AdrianFrühwirth:谢谢,但是
cut-f1,3-
是不可移植的,在我的OSX上不受支持。你不应该使用
awk'{sub($2ofs,”)”1'
由于$2中的同一文本可能位于$1的末尾,和/或$2可能包含RE元字符,因此很有可能以这种方式删除错误的字符串。@anubhava-不,在另一个字符串中查找字符串而不是REs的唯一awk函数是index()@anubhava-正确,没有简单的方法,但请查看我的答案,以获得可靠的方法。额外的
1
在这里有什么作用?@shiplu.mokadd.im
1
的计算结果为true,该值在默认块(
{print$0}
)中生效。它不会清理任何内容,但与所有现有字段的重写一样,它会替换
IFS
(一行中的一个或多个)转换为单个
OFS
。例如,这是实现“规范化空间”过滤器的一种方法:
awk'{$1=$1}1'
不会清理多余的空间,使用不需要的
print$0
可以被简单的
1
@Jotne替换。当我使用
1
代替
print$0
时,我不会从awk获得任何输出。你确定它们是等效的吗?@Alex删除
print$0
并在关闭
后放入
1
。看看这些复杂的情况,你会怀疑awk是否真的是这项工作的最佳工具。例如,如果字段用管道或逗号分隔,那么整个awk代码都需要重写。这取决于你的输入。如果字段之间只有一个字符,那么
cut
就更好了。如果你还有其他东西,那么gawk+gensub()或sed(在语法上非常相似)可能是最好的选择。当试图描述多字符REs的否定时,这两个选项都会遇到问题,因此您需要看看gawk+patsplit()或者gawk+FPAT。不幸的是没有银弹。回答得很好,我希望我能+2你。一个问题是代码比循环解决方案的
长得多。f@shiplu.mokadd.im-正确,但它保留了原始的空白,而您发布的for循环不会产生您指定的输出。顺便说一下,请编写您发布的for循环-ne在输入数据中使用printf,例如,
printf$1
,因为如果您的输入数据包含printf格式字符,例如
%
,则会非常失败。请始终使用
printf“%s”和$1
来打印输入数据。另外,打印换行符只需
print”“
,不需要
printf”\n