Rom*_*las 3 ksh text-processing cut
我已经问过几乎相同的问题,但是这一次,我想检索CSV 文件行的 X 个最新元素。例如,输入文件如下:
1;foo;bar;baz;x;y;z
2;foo;bar;baz;x;y;z
3;foo;bar;baz;x;y;z
Run Code Online (Sandbox Code Playgroud)
cut获取最后两列的命令(最终使用)是什么,所以我得到:
y;z
y;z
y;z
Run Code Online (Sandbox Code Playgroud)
事实上,我的真正目标是检索每行的前 3 个和最后 2 个字段,所以我得到:
1;foo;bar;y;z
2;foo;bar;y;z
3;foo;bar;y;z
Run Code Online (Sandbox Code Playgroud)
不幸的是,我不能使用像cut -d \; -f 1-3,10-11(如果行中有 11 个元素)这样的命令,因为 CSV 文件不尊重真正的CSV 格式。事实上,行中间的一些字段是加密的,它们的加密值有时可能包含一个;字符(当然,它们没有被包裹在里面")。换句话说,我的台词可能是这样的:
1;foo;bar;#@$"é&^l#;baz;x;y;z
2;foo;bar;#¤=é;)o'#;baz;x;y;z
3;foo;bar;#]]'~é{{#;baz;x;y;z
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,在第二行,有一个额外的;字符,所以我不能在这里使用像这样的命令cut -d \; -f 1-3,7-8,因为 if 会返回那个,这是错误的:
1;foo;bar;y;z
2;foo;bar;x;y (-> Wrong here, there is a shift)
3;foo;bar;y;z
Run Code Online (Sandbox Code Playgroud)
那么我该如何使用cut来解决我的问题呢?
谢谢
ps:我特别喜欢这个cut命令,所以如果你有一个可以做我想要的但不是我想要的命令cut,那也没关系:)
编辑似乎很重要的是要注意机器很旧:uname -a给出以下消息:
SunOS ###### 5.10 Generic_142900-05 sun4u sparc SUNW,Sun-Fire-V240
Run Code Online (Sandbox Code Playgroud)
并且某些命令可能不存在(例如rev)
这是一个多命令解决方案,用于仅使用cut, rev(用于逆向)和 shell 内置来检索前 3 个和最后 2 个字段:
while read line
do
first=$(echo -n "$line" | cut -d ";" -f -3)
second=$(echo -n "$line" | rev | cut -d ";" -f -2 | rev)
echo "$first;$second"
done < my_file
Run Code Online (Sandbox Code Playgroud)
当然,这些语句也可以放在一行中。
编辑:
我收集了一些单行替代方案rev(省略打印最后的'\n'):
Python: python -c "import sys; sys.stdout.write(raw_input()[::-1])
珀尔: perl -ne 'chomp;print scalar reverse;'
并且反转字符串有更多的可能性。也许其中一些适用于您的系统。
在您的版本SunOS nawk(或就此而言awk)应该能够做到这一点
nawk -F';' 'BEGIN{OFS=";"}{print($1,$2,$3,$(NF-1),$(NF))}' file.txt
Run Code Online (Sandbox Code Playgroud)