剪切命令,顺序未保留?

剪切命令,顺序未保留?

我有一个示例文件:-

[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
}

相关内容