我有一个文件,每行中有很多行,每行有很多列(字段),用空格“”隔开,每行中的列数不同。我想删除前两列怎么办?
Answers:
您可以使用cut:
cut -d " " -f 3- input_filename > output_filename
说明:
cut:调用cut命令-d " ":使用单个空格作为分隔符(cut默认情况下使用TAB)-f:指定要保留的字段3-:以字段3开头的所有字段input_filename:使用此文件作为输入> output_filename:将输出写入此文件。或者,您可以使用awk:
awk '{$1=""; $2=""; sub(" ", " "); print}' input_filename > output_filename
说明:
awk:调用awk命令$1=""; $2="";:将字段1和2设置为空字符串sub(...);:清理输出字段,因为字段1和2仍将由“”分隔print:打印修改后的行input_filename > output_filename:与上述相同。cut默认使用制表符作为分隔符。查看更新的答案-刚刚经过测试,即可正常工作。在其他条件相同的情况下,我建议使用cutover awk。
awk '{sub(/([^ ]+ ){2}/, "")}1'。我同意,如果您有单字符字段分隔符,无论如何,cut是更好的选择。
awk '{$1=""; $2=""; sub(/^ +/, ""); print}'代替,或者用更短的空格awk '{$1=$2=""; sub(/^ +/, "")}1'
这是使用Awk相对容易理解的一种方法:
awk '{print substr($0, index($0, $3))}'
这是一个简单的awk命令,没有任何模式,因此将对{}每个输入行运行内部操作。
操作是仅从第三个字段的位置开始打印子字符串。
$0:整个输入行$3:第三场index(in, find):返回find字符串中的位置insubstr(string, start):返回从索引开始的子字符串 start如果要使用其他定界符(例如逗号),则可以使用-F选项进行指定:
awk -F"," '{print substr($0, index($0, $3))}'
您还可以通过在中的操作之前指定模式来对输入行的子集进行操作{}。只有与模式匹配的行才会执行操作。
awk 'pattern{print substr($0, index($0, $3))}'
模式可以是这样的:
/abcdef/:使用正则表达式,默认情况下对$ 0进行运算。$1 ~ /abcdef/:在特定字段上操作。$1 == blabla:使用字符串比较NR > 1:使用记录/行号NF > 0:使用字段/列号感谢您发布问题。我还想添加对我有帮助的脚本。
awk '{ $1=""; print $0 }' file
OFS=FS以保留定界符:unix.stackexchange.com/a/252748/112834
您可以使用sed:
sed 's/^[^ ][^ ]* [^ ][^ ]* //'
这将查找以一个或多个非空白,一个空格,另一组一个或多个非空白和另一个空格开头的行,并删除匹配的材料,也就是前两个字段。它[^ ][^ ]*比等效但更明确的[^ ]\{1,\}符号略短,并且第二个符号可能会与GNU发生问题sed(尽管如果您将其--posix用作选项,即使GNUsed也无法解决)。OTOH,如果要重复的字符类别更为复杂,则为简明起见,用数字表示法是可以取胜的。很容易将其扩展为将“空白或制表符”作为分隔符,或“多个空白”或“多个空白或制表符”。还可以对其进行修改,以处理第一个字段之前的可选前导空白(或制表符),等等。
对于awk和cut,请参阅Sampson-Chen的答案。还有其他编写awk脚本的方法,但是从本质上说,它们并不比给出的答案更好。请注意,如果您不希望将制表符视为分隔符,则可能需要显式设置字段分隔符(-F" "),awk否则字段之间可能会有多个空白。POSIX标准cut不支持字段之间的多个分隔符。GNUcut具有有用但非标准的-i选项,以允许在字段之间使用多个分隔符。
您也可以在纯shell中执行此操作:
while read junk1 junk2 residue
do echo "$residue"
done < in-file > out-file
residue可以包含反斜杠,则上述读取内容将对其进行解释,而不会在输出中复制它。始终使用while IFS= read -r ...。
bash用一个简单的解释内容read,那么bash(再次)被破坏。原始shell中的read命令并没有废话。我认为POSIX shell不需要它。这会激怒我,bash让您发现自己确实做到了—我已经与该程序建立了爱恨交织的关系,因为它在很多方面做得很好,但是有些事情做得不好,并且不断变化遗留行为是最糟糕的行为之一,并且要求启用旧的标准行为的选项非常烦人。看来你是对的;bash很无聊!
residue将从字段4(或更高版本)而不是字段3开始。
bash它紧随POSIX2008 。我从不希望在超过四分之一世纪的Shell编程中使用该功能,但我想我应该很少。
仅使用外壳即可做到这一点
while read A B C; do
echo "$C"
done < oldfile >newfile
read -r代替read。
read -r将保留反斜杠。read将不会。例如:echo "foo ba\r"将产生输出foo ba\r。但是,echo "foo ba\r" | (while read first_column second_column; do echo "$second_column"; done)将产生bar与输出相同的结果(去掉反斜杠。添加-r标记会产生正确的输出ba\r