我有一个示例文件:-
[root@localhost base_filters]# cat shortlist
2233|charles harris |g.m. |sales |12/12/52| 90000
9876|bill johnson |director |production|03/12/50|130000
5678|robert dylan |d.g.m. |marketing |04/19/43| 85000
2365|john woodcock |director |personnel |05/11/47|120000
5423|barry wood |chairman |admin |08/30/56|160000
我想翻转文件中的名称,以便,
在姓氏后面有一个逗号,例如名称应显示为 harris,charles。
我尝试了以下命令:-
[root@localhost base_filters]# tr -s ' ' < shortlist | cut -d\| -f2 | cut -d' ' -f2,1
charles harris
bill johnson
robert dylan
john woodcock
barry wood
我希望姓氏首先出现,所以我指定了字段 2,然后指定了 1,但这似乎不起作用。对此有什么想法吗?
答案1
使用 可以轻松完成此操作awk
。首先打印出名称,然后再次将输出通过管道传输到 awk(这次使用空格作为文件分隔符)。
awk -F "|" '{print $2}' extract.txt | awk -F " " '{print $2 "," $1}'
答案2
cut 的手册页说
所选输入的写入顺序与读取顺序相同,并且只写入一次。
所以你必须使用另一种工具而不是切割。例如 sed、awk、perl、python 或 bash。
答案3
以下函数将仅使用 Bash 内置函数(如果您想使用 Bash )来执行您想要的操作:
foo ()
{
local filename="$1"
while IFS='|' read -r pre name suf; do
l="$pre|${name#* },${name% *}|$suf";
printf '%s\n' "$l";
done < "$filename"
}
这IFS变量设置为 | 'read' 一次读取每一行“1美元”(您的文件)并将其分为三个部分,$前$名称和$suf,根据 IFS 值。
$前值设置为名称之前的字段,$名称设置为您要交换的名称本身(第二个字段)并且$suf是该行的其余部分。
我用参数扩展(也可以在 中搜索 Parameter Expansion man bash
)来拆分$名称场地。
"${name#* }"
将删除名字,留下姓氏。
"${name% *}"
将删除姓氏,留下名字。
用法:foo [/path/to/file.txt]
示例输出:
nylon100@~$ cat>file.txt
123|first1 last1|foo|bar|date|baz
456|first2 last2|foo|bar|date|baz
789|first3 last3|foo|bar|date|baz
nylon100@~$ foo file.txt
123|last1,first1|foo|bar|date|baz
456|last2,first2|foo|bar|date|baz
789|last3,first3|foo|bar|date|baz
答案4
尝试:
tr -s ' ' < shortlist | cut -d\| -f2 | tr '\n' ' ' | tac -s' ' | \
sed -e 's/^[[:space:]]//' -e 's/ /\n/g' | sort
或者,如果您有许多这样的文件:
sortnames () {
tr -s ' ' < $1 | cut -d\| -f2 | tr '\n' ' ' | tac -s' ' | \
sed -e 's/^[[:space:]]//' -e 's/ /\n/g' | sort
}